1、开发环境
(1)Keil MDK: V5.38.0.0
(2)STM32CubeMX: V6.8.1
(3)MCU: STM32F407XGT6
2、PWM简介
2.1、什么是PWM
(1)PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。
(2)PWM信号仍然是数字的,因为在给定的任何具体时刻,满幅值的直流供电要么完全有,要么完全无。就像单片机的引脚,要么是输出高电平,要么是输出低电平。
(3)PWM波本质是是一种方波,一段高电平,一段低电平,如此循环。
(4)举例说明。现在有一颗灯,该灯只能打开或者关闭。在足够高的频率下,固定周期的开灯关灯(假设周期是10uS,开灯x微妙,关灯10-x微妙);这种情况下,是感受不到灯熄灭的,开灯所占时间越多,灯的亮度就越大。
2.2、PWM相关的概念
(1)占空比:也就是输出的PWM中,高电平保持的时间与该PWM的周期的时间比。
(2)分辨率:例如要表示0-100的模拟量,12为的PWM,分辨率就是100/0xFF。
(3)频率:PWM波的周期的倒数。
(4)模拟量:连续变化的量。例如自然界中的温度,有2℃,2.1℃,2.1335...℃。
(5)数字量:计算机中存储的温度,假设用4个bit位来表示0-100的温度,温度的分辨率就是100/0xFF,温度值不可能非常精确到小数点后一百万位。
3、使用Timer实现PWM输出
3.1、没有PWM输出的定时器
(1)没有PWM输出的定时器只能自己定时设置中断,在中断中翻转电平。
(2)这样的缺点是比较麻烦,因为还要有ISR(Interrupt Service Routines: 中断服务程序)。
(3)这样的PWM周期没有那么精准,因为中断的跳转和执行本身需要消耗一定时间。
3.2、有PWM输出的定时器
(1)高性能的单片机定时器都有PWM输出功能,以前的51单片机就没有,现在的晓不得。
(2)例如定时器的计数值比如是0~100,设定一个比较值X。
(3)计数值大于比较值X,某引脚输出高电平;计数值小于比较直X,某引脚输出低电平。
(4)这个引脚大部分单片机是内部绑定了的,少部分可以通过软件进行设置。
(5)通过定时器的计数值和设定的比较值进行比较,输出不同的电平,这就是输出比较功能。
(6)输出比较功能是不需要中断的,时间到了电平是自动翻转的,在内部硬件的电路逻辑已经定好了。
(7)STM32中,使用PWM功能自动绑定了一个引脚。单片机设计的时候,每一路PWM输出都绑定了一个GPIO引脚。
4、示例程序目的&原理图
4.1、示例程序目的
(1)使用PWM输出,控制LED灯亮度,LED由灭逐渐变为LED最亮。
(2)PWM周期100uS。
(3)默认LED灯度50%。
(4)不是所有的GPIO都支持PWM输出。
4.2、原理图
(1)LED1,接PF9引脚。
5、STM32CubeMX创建工程及配置
5.1、创建工程
(1)打开STM32CubeMX软件。
(2)点击File→NewProject。
(3)Commercial Part Number(商用部件号)处输入MCU型号,然后选择正确的单片机型号,点击Start Project(开始项目)。
(4)配置工程名、工程存放文件等。
点击Project Manager(项目经理)进行如下配置。
点击Code Generator(代码生成器)进行如下配置。
(5)点击GENERATE CODE生成KeilMDK工程。
5.2、配置时钟源和GPIO
(1)HSE、LSE时钟源头选择
- HSE:高速外部时钟源
- LSE:低速外部时钟源
- Disable:禁用
- BYPASS Clock Source:旁路时钟源
- Crystal/Ceramic Resonator :水晶/陶瓷共振器
- 一般选择水晶陶瓷共振器
- 旁路时钟源就是由外部给定一个时钟信号,一般用于作为同步时钟。
- 水晶/陶瓷共振器:指外接晶振,经过内部振荡电路产生时钟。
(2)LED1引脚配置,配置定时器后会变绿的。
(3)时钟树配置
5.3、配置定时器
(1)使能定时器并选择通道功能。
- 勾选Activated,不能选择时钟源的时钟源为内部时钟。
- PWM Generation CH1:配置通道1为PWM生成
(2)定时器Parameter Settings(参数设置)。
- PWM周期100微秒,也就是定时时长100微秒。
- 占空比:50%。也就是LED_PWM输出有效电平占比50%。
- Prescler(PSC -16 bits value): 分频系数,选择72-1,进行72分频,即定时时钟变为72MHz/72 = 1MHz=1000000Hz。
- Counter Mode: 计数器模式,选择Up,向上计数。
- Counter Period (AutoReload Register-32 bits value): 计数器周期,16位自动加载值。
- 时钟频率1000000Hz表示1秒钟时钟振荡1000000次。
- Counter Period = 100us/(1/1000000Hz) =100uS/(1/1000000S) =100 。
- Mode:PWM mode 1。递增计数时,当计数值 < 比较值,输出为有效电平,否则为无效电平。
- Pulse:比较值,设置50%有效电平。设为50。
- CH Polarity:有效电平是高电平还是低电平。
- PWM Generation Channel 1配置详解见后文。
6、Keil MDK软件的编写
6.1、程序编写
/************************************
*PWM输出有效电平为低电平。
*定时器计数值 < 比较值,输出低电平;
*定时器计数值 >=比较值,输出高电平。
*比较值设置越大,LED灯越亮。
*定时器计数值范围:0-99
*比较值范围:0-100;0,LED灯灭;99,LED最亮。
*LED亮50%,计数值为50。
************************************/
HAL_TIM_PWM_Start(&htim14, TIM_CHANNEL_1);
while (1)
{
/*比较值越大,LED越亮;LED逐渐变亮*/
for(uint8_t i = 0; i <= 99; i++)
{
__HAL_TIM_SetCompare(&htim14, TIM_CHANNEL_1, i); /*设置比较值*/
HAL_Delay(30);
}
}
6.2、完整工程下载地址
(1)完整工程存储再码云。
(2)STM32_CSDN: CSDN中STM32专栏的所有示例代码
7、定时器PWM配置详解
7.1、PWM mode 1和PWM mode 2
(1)在进行PWM信号输出时,有两种PWM模式:PWM1模式和PWM2模式。这两种PWM模式和输出有效电平的极性共同决定了PWM信号的波形。
(2)PWM1模式。递增计数时,当TIMx_CNT(计数值)< TIMx_CCR(比较值)时,输出为有效电平,否则为无效电平。递减计数模式则刚好相反。
(3)PWM2模式。递增计数时,当TIMx_CNT(计数值) < TIMx_CCR(比较值)时,输出为无效电平,否则为有效电平。递减计数模式则刚好相反。
(4)更多细节可参考相应芯片的参考手册。应为参考手册可搜索TIMx_CNT<TIMx_CCR1
找到相应内容。
7.2、PWM占空比和比较值
(1)占空比: 高电平保持的时间与该PWM的周期之比。
(2)STM32中输出的有效电平不一定是高电平,是可以设置的。
(3)PWM输出有效电平比举例:配置50%的有效输出,定时器计数周期9。比较值为5时,0、1、2、3、4输出有效电平。5、6、7、8、9输出有效电平的相反电平。