stm32F407之PWM实现呼吸灯效果
PWM:脉冲宽度调制,可以理解为,PWM波形,是通过调整其频率和占空比来达到我们需要的波形或是等效电压,通过占空比替代波形曲线。
概念
- 频率:整个PWM波的频率,即时钟频率
- 占空比:脉冲的有效电平占整个周期的百分比
任务
两个LED灯,实现呼吸灯效果
- 定时器频率为1000HZ
- 时钟预分频:83
- 计数器:999
- 定时器频率计算为:84000000/84/1000=1000HZ
硬件
- LED2<-->PA1<-->TIM2.Channel2通道
- LED3<-->PA2<-->TIM2.Channel3通道
- 不同GPIO会连接不同的TIM的不同Channel,配置GPIO和TIM是要注意
配置
- SYS,RCC与前面的配置相同,需要注意的是,TIM默认的输出时钟是84M
- GPIO:引脚可以先设置,然后在TIM标签下设置定时器的参数
- LED2连接PA1引脚,引脚设置位TIM2_CH2
- LED3连接PA2引脚,引脚设置位TIM2_CH3
- TIM:
- Clock Source:interal clock
- channel2\3:PWM Generation CH2/3(打开两个通道的PWM功能)
- 预分频和计数器按照上面配置,分别为83和999;
- PWM Channel配置:Mode:PWM mode1;pulse(暂不配置,后面在代码里动态配置);CH Polarity:low
- 启用NVIC使能
实现
通过动态调整pulse的值,动态实现不同的占空比,在不同占空比下,TIM实现了不同的输出电压,LED灯在不同电压下,亮度动态变化,从而实现呼吸灯的功能。
main.c
前面介绍了TIM定时器的函数调用流程,这里就不再介绍调用方式。另外定时器动态调整输出的电压到GPIO引脚,也无需实现TIM的中断回调函数。
启用定时器的PWM功能
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
动态调账PWM的占空比
uint16_t dutycycle=0;
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
while(dutycycle<1000)
{
dutycycle++;
// __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,dutycycle);
TIM2->CCR2 = dutycycle;
// __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_3,dutycycle);
TIM2->CCR3 = dutycycle;
HAL_Delay(1);
}
while(dutycycle)
{
dutycycle--;
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,dutycycle);
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_3,dutycycle);
HAL_Delay(1);
}
HAL_Delay(100);
}
/* USER CODE END 3 */
}
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,dutycycle);
设置PWM的占空比:
- 第一参数都是定时器
- 第二参数为通道
- 第三参数为占空比的计数值
补充说明:
- PWM的MODE:PWM mode 1和PWM mode 2互补
- PWM Mode 1:当定时器计数为向上计数,则计数小于占空比的部分为有效电
- PWM Mode 2:当定时器计数为向上计数,则计数大于占空比的部分为有效电平
- Pulse(脉冲宽度):占空比
- 占空比=(Pulse/自动重载值)*100%
- 自动重载值为定时器的:Counter Period值
- 上面设置的计数器是1000,通过动态调整pulse值,即动态调整占空比
- 看main.c中while中的代码,dutycycle就是动态设置,而且dutycycle不要超过这个数,否则LED灯演示的效果会很奇怪
- CH Polarity(频道有效电平【High/Low】)
- 通道的高低电平根据所驱动的外设进行设置,如LED是高电平驱动,设置为HIGH,则LED灯由暗变亮
__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_2,dutycycle)
与TIM2->CCR2 = dutycycle
具有同样的效果,只是一种是使用HAL库函数,一种是操作寄存器。- 在PWM Mode 1模式下,当计数器使用up(向上)时,CNT<CCR,通道CH为有效,否则为无效