STM32CubeMX的TIM1互補PWM輸出,HAL庫(2路,帶死區)

芯片爲STM32F407ZG,使用的是高級定時器TIM1的PWM互補PWM輸出。
效果:
函數

總體的:(通道0~3分別是CH一、CH1N、CH二、CH2N。)在這裏插入圖片描述
細節:
在這裏插入圖片描述

測試

CH1和CH1N的死區時間是0.375us(公式算出來應該是公式0.3us左右,跟邏輯分析儀的採樣頻率有關係)
CH1和CH二、CH1N和CH2N是同步的,之前作H橋的話就須要這種吧(對角同時導通),有相位差的後面再研究。
spa

STM32CubeMX配置:
在這裏插入圖片描述
main函數

調試

/* USER CODE BEGIN 2 */
	/****普通定時器***/
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);
	/****高級定時器互補輸出***/
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
	HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);
	HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
	/****寄存器方法修改比較寄存器的值,ARR的值cube配置爲1000***/
	TIM1->CCR1=249;
	TIM1->CCR2=249;
  /* USER CODE END 2 */

說明:
代碼中普通定時器只是爲了測試!
高級定時器與普通定時器用法有微笑區別,網上查資料老是誤導,不少教程都提到要用HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1)這一句,可是隻有這一句CH1N會有輸出,CH1就沒了,走了很多彎路。

code

細看高級定時器的函數名,一個是PWM、一個是PWMN,而HAL_TIMEx_PWMN_Start與HAL_TIM_PWM_Start相比多了一個Ex,所在的.c文件也不相同。猜測帶Ex的多是擴展功能吧blog

再來看看死區時間計算吧:
cubemx生成的代碼以下:
教程

void MX_TIM1_Init(void)
{
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 167;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 999;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 99;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.Pulse = 199;
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 50;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_ENABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_TIM_MspPostInit(&htim1);
}

sBreakDeadTimeConfig.DeadTime = 50;這句就是死區時間了,怎麼算,參考STM32F4xx中文參考手冊.pdf
在這裏插入圖片描述
DeadTime 是直接寫入DTG[7:0],顯然,當DeadTime <128時,最高位都是0,按照最上面的那條公式算就行了,DT=50Tdtg,其中,Tdtg=tDTS=1/164Mhz(tim1接在高速時鐘APB2),算出來就是DT=501/164M=0.3048us了

圖片

我的調試心得,感謝點贊,更多問題交流,+Q:cqkz52@qq.com同步

相關文章
相關標籤/搜索