一 、前言
要求产生频率和个数一定的PWM脉冲,一般的思路是一个定时器产生给定频率的PWM脉冲,另一个计数器对该脉冲计数,当达到计数值时关闭PWM输出。
当我们使用定时器的主从模式,将从定时器的时钟设置为主定时器的PWM输出时,即可直接控制从定时器的计数阈值来获取我们需要的PWM脉冲。
二 、主从定时器的设置
2.1 主定时器的配置
主定时器时钟为168HMz时钟,让总值为100-1,半值为50,分频系数为(840/f)-1,就得到 f KHZ的PWM。打开主从模式,触发事件选择为更新事件时
2.2 定时器内部触发
我们需要将从定时器的触发方式设置为主定时器内部触发,以下是参考手册的部分定时器内部触发的表
例如主定时器2、从定时器3,那么定时器3的内部触发为 ITR1(TS = 001)。
按上图设置,其中勾选Slave Mode为 外部时钟1 和触发连接为上表对应的ITRx后,将下面的触发事件选择为输出电压OC1与参考电压REF比较。打开从定时器中断,主从定时器就配置好啦!
三 、 编写从定时器回调函数以及PWM输出函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim) //TIM3达到指定脉冲数回调函数
{
if(htim->Instance == TIM3)
{
if(__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC1) != RESET) //溢出判断
{
__HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_CC1); //清除溢出标志
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_4); //停止主定时器PWM输出
HAL_TIM_Base_Stop_IT(&htim3); //从定时器停止计数
}
}
}
void Generate_PWM(uint32_t f,uint32_t count) //产生 f KHz的 count 个脉冲
{
MX_TIM2_Init(f); //产生f KHz的脉冲的初始化定时器
MX_TIM3_Init();
__HAL_TIM_SET_AUTORELOAD(&htim3, count - 2); //自动重装载值设置
HAL_TIM_Base_Start_IT(&htim3); //开始计数
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4); //打开PWM
}
在初始化定时器2的时候由于设置了变量 f,所以函数名的参数不是void而是uint32_t f,这个在tim.h里面也要改一下。
四 、 结果展示
while (1)
{
/* USER CODE END WHILE */
Generate_PWM(10,5); //包含定时器初始化,输出10Khz脉冲5个
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
} //main函数中的定时器初始化删掉
编译下载
第一个逻辑分析仪测出来的不太稳定,后面的是正常的。