项目中经常使用到STM32来输出PWM,每次配置过后过不了多久就会忘记,稍微需要对配置做出修改时都要翻很久的手册,所以决定结合实例把PWM配置的详细步骤记录下来,这样在下次配置时可以很快的捡起来。
本文档的行文结构如下,首先,说明实际需求,即要输出什么样的PWM信号;然后,根据需求把手册中相关的部分摘抄下来并辅以个人的理解和总结;最后,详细说明在软件中怎么去配置并展示配置后的实验效果。
项目中用到4路PWM信号,硬件条件决定了其只能由定时器1和定时器3产生,每个定时器输出两路PWM信号,要求4个PWM信号相位同步,每个PWM信号如图1所示。
图1 PWM输出波形要求
具体要求见表1。
表1 PWM要求
序号 | 名称 | 要求 | 备注 |
1 |
周期 |
100us |
暂定 |
2 |
占空比 |
0~100%可调 |
|
3 |
中断触发时刻 |
计数器下溢点 |
|
4 |
占空比更新时刻 |
计数器下溢点 |
图 2高级定时器的原理框图
图中用红色虚线框出来的部分是输出PWM所需要的部分,包括时钟源、计数器单元、比较寄存器及PWM输出、TRGO输出、外部触发输入,下面依次说明各部分原理。
计数器时钟可由以下时钟源提供:
输出PWM使用内部时钟(CK_INT),只需要关心怎么配置为内部时钟以及内部时钟的频率。
时钟源输出的时钟经过预分频器分频后作为计数器的时钟。计数器在时钟下可以增计数、减计数、增/减计数。自动重载寄存器控制计数器的计数范围,即定时器的周期。重复计数器控制更新事件UEV产生的频率。
预分频器用于对计数器时钟进行分频,分频系数可配置为1~65536。分频系数可以动态修改,不过其具有缓冲功能,修改后的分频系数只能在下一次更新事件UEV后生效(见3.2.3节)。
1)计数器可以增计数、减计数、增\减计数。
2)自动重装值可以配置为预装载或者不预装载。不预装载时,自动重装值实时生效;预装载时,自动重装值在下一次更新事件UEV后生效(见3.2.3节)。
3)增/减计数有3种,分别为中心对称模式1/2/3,区别在于输出比较中断标志触发的位置不同,具体见手册。
1.重复计数器
重复计数器仅用来控制更新事件的产生。它是一个自动重装的减计数器,在更新事件UEV时自动重装,重装值为RCR寄存器的值。每次上溢或下溢事件时重复计数器减1。
2.更新事件的产生
更新事件(UEV)可以被屏蔽或者启用(TIM_CR1的UDIS位)。被屏蔽的情况下不会产生任何更新事件;被启用的情况下,有两种情况可以产生更新事件,分别为外部触发和计数器内部触发。
外部触发不受重复计数器的影响,只要触发则立即产生更新事件。外部触发有两种,分别为软件向TIM_EGR的UG位写1和外部触发输入(见3.5节)。
计数器内部触发受重复计数器的影响,只有重复计数器等于0时才可以产生更新事件。在重复计数器等于0时以下三种情况可以产生更新事件:
结合重复寄存器的原理可知,每N(RCR寄存器的值)+1次上溢或者N+1
次下溢事件产生1次更新事件 。
3.增\减计数模式下如何控制更新事件(UEV)在上溢还是下溢产生?
显然,增\减计数模式时如果配置重复寄存器RCR为奇数,更新事件将只能在上溢或下溢产生,那么该如何控制其在上溢还是在下溢产生呢?手册中写到:在启动计数器前写入RCR,则UEV将在上溢时产生,在计数器启动后写入RCR,则UEV将在下溢时产生。
但经过实测试上述说法并不完全准确。实测结果如下:
可以这么理解,启动计数器后首先触发的是上溢事件,然后是下溢事件。因为重复计数器是一个在更新事件UEV时自动重装载的计数器,在启动计数器前写入的1并没有装载到重复计数器,所以启动计数器后更新事件UEV在上溢产生;如果在启动计数器前软件强制触发一个UEV事件,则在启动计数器时1已经写入重复计数器,所以更新事件UEV在下溢产生。
至于启动计数器后写入RCR的现象则更好解释。因重复计数器只在UEV时更新,写入RCR后不会立马更新,所以增计数在上溢产生UEV事件然后更新重复计数器,减计数在下溢产生UEV事件然后更新重复计数器。
图 3不同模式和配置下的更新事件(UEV)的触发时刻
比较寄存器(TIM_CCRx)可以配置为预装载和不预装载。预装载时,只有在下一次更新事件UEV时比较寄存器的值才会生效,不预装载时,比较寄存器的值实时生效。配置为PWM模式时必须使能预装载(使用HAL库配置为PWM模式时默认已使能预装载)。
比较寄存器可以配置为PWM模式和其他模式。这里仅介绍PWM模式,其他模式见手册比较输出模式章节。PWM模式分为PWM模式1和PWM模式2。
PWM模式1时:
图 4 PWM模式1、中心对齐模式的PWM波形
PWM模式2时:
注意事项:不建议在运行中心对齐模式(增\减计数)时对计数器执行写操作,使用中心对称模式最为保险的方法为:在启动计数器前通过软件生成更新(对TIM_EGR的UG位写1)来初始化所有寄存器(HAL库中有此操作),并且不要在计数器运行过程中对其执行写操作。
TRGO输出受TIM_CR2寄存器MMS位控制,具体如图5。
图 5 TRGO输出配置
MMS为010时,更新事件UEV作为TRGO输出,可用于同步其他定时器。
定时器配置为从模式可与外部触发输入同步,有三种同步模式,分别为复位模式、门控模式和触发模式,这里仅介绍复位模式,其他模式见手册。复位模式:触发事件时,计数器和预分频器将重新初始化,同时还会生成更新事件UEV,所有的预装载寄存器将会更新。触发输入可选:
其中ITR0~ITR3是从定时器的内部触发输入,是主定时器的TRGO输出。当定时器3作为从定时器时,它对应的内部触发输入来源如下:
表 2 定时器3作为从定时器时的触发输入来源
从定时器 |
ITR0 |
ITR1 |
ITR2 |
ITR3 |
TIM2 |
TIM1 |
TIM15 |
TIM3 |
TIM14 |
硬件条件决定了只能使用定时器1和定时器3各输出两路PWM信号。为实现同步,配置定时器3为从模式,使用定时器1的触发输出(TRGO)进行同步复位。
图 6 CubeMx中定时器1的配置1
图 7 CubeMx中定时器1的配置2
图 8 CubeMx中定时器2的配置
图 9 程序中的配置1
图 10 程序中的配置2
实验结果如图10和图11所示,定时器1和定时器3的PWM输出同步,周期为10kHz,占空比为25%;定时器1的更新事件在下溢点触发,每个增\减计数周期触发1次。
图 11 实验效果1-PWM信号周期、占空比、同步关系
图 12 定时器1更新事件UEV触发时刻