【PWM】彩色呼吸灯
下载例程代码: 下载代码
请一定按照 例程使用方法🔗 导入例程,否则下载的可能不是例程而是其他工程。
PWM 简介
PWM 波形
PWM波形是一种方波信号,是高/低电平不断切换的结果,其波形如图所示,这是3种占空比不同的波形:

PWM的几个关键参数为:
-
频率(Frequency):即高低电平切换的速度,切换的速度越快则频率越高,1000Hz的PWM波意味着1秒钟有1000个脉冲
-
占空比(Duty Cycle):即每个周期内,高电平所占的宽度
-
例如图中
50% duty cycle
,即高/低电平的时间各占50%; -
图中的
75% duty cycle
,高电平占75%,低电平占25%; -
图中的
25% duty cycle
,高电平占25%,低电平占75%;
-
PWM 实现呼吸灯
如果使用PWM信号控制LED的亮/灭,那么占空比越高,灯点亮的时间就越长
因此,当PWM频率足够高,以至于人眼无法分辨时,PWM的占空比就可以控制LED灯的亮度
也就是说,占空比越高,LED看起来越亮
此例程使用PWM来驱动学习板上的RGB LED,实现呼吸灯效果
如何使用例程
下载程序,即可看到效果
程序效果
- 烧录例程后,可以看到RGB灯渐变效果
- 修改一下例程可以实现不同颜色、不同速度的呼吸灯效果

例程讲解
下面介绍了如何自己实现该例程的功能
1、工程配置
- 开启外部晶振:在Pinout&Configuration -> System Core -> RCC 页面,将 High Speed Clock (HSE) 配置为 Crystal/Ceramic Resonator

- 配置时钟频率:在Clock Configuration 页面,将PLL Source 选择为 HSE,将System Clock Mux 选择为 PLLCLK,然后在HCLK (MHz) 输入72并回车,将HCLK频率配置为 72 MHz

-
分配引脚:在Pinout&Configuration页 面,将PA6、PA7、PB0分别配置为TIM3_CH1、TIM3_CH2、TIM3_CH3
-
配置TIM3:在Pinout&Configuration -> Timers -> TIM3
-
勾选 Internal Clock,开启 TIM3 的内部时钟源
-
Configuration -> Mode,将 Channel1、Channel2、Channel3 分别配置为 PWM Generation CH1、2、3
-
Configuration -> Parameter Settings -> Counter Settings,将 Prescaler 配置为 72-1,将 Counter Period 配置为 100-1,使PWM频率为10kHz
PWM频率 = 72MHz ÷ 72 ÷ 100 = 10 kHz
-
2、代码
-
启动PWM输出
//启动3个通道的PWM输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); -
在while循环中逐渐改变占空比
-
__HAL_TIM_SET_COMPARE
可以设置PWM的占空比,范围 0 - 99注意:占空比必须小于前面配置的Counter Period,例程中配置为100-1,即占空比可调范围是 0 - 99
-
先从0逐渐增加到99,亮度逐渐提高
-
再从99逐渐减小到0,亮度逐渐降低
while (1) {
// PWM通道CH1-3分别对应三个颜色,下面示例三个颜色一起呼吸灯
// 0-99为占空比,0为最小亮度,99为最大亮度
// 每7ms调整一次占空比,从0逐渐增加到99
for (int period = 0; period < 100; period++) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, period);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, period);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, period);
HAL_Delay(7);
}
// 从99逐渐减小到0
for (int period = 99; period >= 0; period--) {
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, period);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, period);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, period);
HAL_Delay(7);
}
HAL_Delay(100);
} -