互补的PWM经常用到,还得带死区保证安全。使用高级定时器TIM1和TIM8容易实现。最近发现通用定时器TIM2~TIM5也可以实现。技巧是,使用中心计数模式。 简单好用。
/* TIM4 init function */
void MX_TIM4_Init(void) //
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode =TIM_COUNTERMODE_CENTERALIGNED3; //中心计数模式
htim4.Init.Period =210-1;//84MHz/200KHz/2=210 MCU主频168MHz,定时器时钟频率84Mhz
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.Pulse = 210/2-1;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
sConfigOC.Pulse = 210/2-1-5;//后面这个减5,就是死区。单个死区占空比是 5/420=1.2%
if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_MspPostInit(&htim4);
}
启动运行的话,使用这个函数:
HAL_TIM_OC_Start(&htim4,TIM_CHANNEL_1);//启动TIM4的PWM输出。
HAL_TIM_OC_Start(&htim4,TIM_CHANNEL_2);//启动TIM4的PWM输出。
如果做开关电源的驱动信号的话,这里启动函数有个小隐患,HAL库函数不支持2个通道同步启动或者停止。。。。。只能使用LL库操作比较好。
修改占空比的话,使用这个函数:
__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,xxxx/2-1); //xxxx是定时器比较的计数值
__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_2,(210-xxxx)/2-1-5);
来源: 整理文章为传播相关技术,网络版权归原作者所有,如有侵权,请联系删除。