一、思路理解
所谓主从,就是一个做主,一个听从。
思路:使用两个定时器,主定时器用于产生PWM波,从定时器作为计数器使用。假设计数器的中断触发值为100,计数器将主定时器产生的PWM波当作脉冲信号进行计数,当计数器的计数值达到中断值100,则触发计数器中断,关闭主定时器和计数器。综上所述,控制计数器的中断值,我们能修改我们需要发出的脉冲数。另外,对于更改脉冲的频率等操作,可以在对定时器进行配置时修改。
其他思路:与前一个思路类似,使用两个定时器,主定时器用于计数器使用,从定时器输出PWM波。假设计数器的中断值为70,溢出值为100。当计数器到达中断时,启动从定时器输出PWM波,当计数器达到溢出值时,关闭从定时器输出PWM波,这样我们就可以输出30个的PWM波。
二、主从定时器选取
如下图,选取TIM3为主定时器,TIM4为从定时器,ITR2触发。
三、CubeMX配置
主定时器TIM3配置。
关于频率:
- f是PWM的输出频率
- APB1 是定时器的时钟源频率(可以从时钟树上获得,本次测试为72MHZ)
- Prescaler 是自动重装载寄存器的值,本次设置的数值是72-1
- CounterPeriod 是预分频器寄存器的值,本次设置的数值是100-1
- DutyRatio 是占空比,本次设置为50-1
可以算出 ,即10000Hz,10KHz。
修改此处可以更改PWM输出的频率。
从定时器TIM4配置。
使能中断。
到此,配置完成。生产代码,再keil5中进行编写。
定时器TIM4中断函数。
void TIM4_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim4);
}
此函数不需要自己补充,在前面CubeMX配置了NVIC后,会自动帮你生成。放在了stm32fxx_it.c中。
在tim.c中编写计数器中断函数和指定数量PWM输出函数。
函数执行顺序是先启用Generate_PWM,将主从定时器都开启,输出PWM波,且计数器进行计数,当计数器计数值到达中断设定值,进入回调函数,关闭主从定时器,结束PWM输出。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) //中断回调函数,到达设定的脉冲数进入此函数执行
{
if(htim->Instance == TIM4)
{
if(__HAL_TIM_GET_FLAG(&htim4, TIM_FLAG_CC1) != RESET)
{
__HAL_TIM_CLEAR_FLAG(&htim4, TIM_FLAG_CC1); //清楚标志
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1); //关闭PWM输出
HAL_TIM_Base_Stop_IT(&htim4); //关闭定时器中断
}
}
}
void Generate_PWM(uint32_t count) //产生PWM函数
{
__HAL_TIM_SET_AUTORELOAD(&htim4, count - 1); //重新设置自动重装值
HAL_TIM_Base_Start_IT(&htim4); //启动定时器中断
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); //启动PWM输出
}
将补充的函数添加到头文件tim.h中,方便调用。
编写测试代码。延时500ms发送是个脉冲。
Generate_PWM(10);
HAL_Delay(500);
在主函数中编写。
编译,烧录。
三、测试
使用逻辑分析仪观察现象。
第一段PWM波和第二代PWM波中间产生500ms延时。
放大,观察PWM波。
参考文章:
基于STM32F4 定时器主从模式输出固定数量PWM脉冲_stm32f407输出固定数量脉冲-CSDN博客
STM32CUBEMX配置定时器主从模式,发送指定个数脉冲,驱动步进电机精确启停_stm32 使用定时器发送单个脉冲的pwm波-CSDN博客