脉冲宽度调制模式允许您生成一个信号,其频率由TIMx_ARR
寄存器的值确定,占空比由TIMx_CCRx
寄存器的值决定。
通过在TIMx_CCMRx寄存器的OCxM位中写入'110'
(PWM mode 1)或'111'
(PWM mode 2),可以在每个通道上独立选择PWM模式(每个OCx输出一个PWM)。您必须通过在TIMx_CCMRx寄存器中设置OCxPE位来启用相应的预装载寄存器,并最终通过在TIMx_CR1寄存器中设置ARPE
位来启用自动重装载预加载寄存器(在递增计数或中心对齐模式下)。
由于只有当更新事件发生时,预加载寄存器才会传输到影子寄存器,因此在启动计数器之前,您必须通过设置TIMx_EGR寄存器中的UG
位来初始化所有寄存器。
OCx极性可使用TIMx_CCER寄存器中的CCxP
位进行软件编程。它可以被编程为高电平有效或低电平有效。OCx的输出是由CCxE
、CCxNE
、MOE
、OSSI
和OSSR
位(TIMx_CCER和TIMx_BDTR寄存器)的组合来使能的。有关更多详细信息,请参阅TIMx_CCER寄存器说明。
在PWM模式(1或2)下,TIMx_CNT 和 TIMx_CCRx 总是进行比较,以确定TIMx_CCRx ≤ TIMx_CNT
还是TIMx_CNT ≤ TIMx_CCRx
(取决于计数器的计数方向)。
定时器能够根据 TIMx_CR1 寄存器中的CMS
位在边缘对齐模式或中心对齐模式下生成PWM。
PWM边缘对齐模式
向上计数配置
当 TIMx_CR1 寄存器的DIR
位为低电平时,递增计数有效。参见第225页的递增计数模式。
在以下示例中,我们考虑PWM模式1。只要TIMx_CNT<TIMx_CCRx
,PWM参考信号OCxREF就为高,否则它就变低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR中),则OCxREF保持在1
。如果比较值为0,则OCxREF保持在0
。
图72,显示了TIMx_ARR=8
示例中的一些边缘对齐PWM的波形。
这张图中的CCxIF
文中没提到,它的含义如下,由于x
代表的是通道,以CC1IF
(TIM1_SR中)为例:
如果通道CC1配置为输出:
当计数器的值与比较值匹配时,该标志由硬件置位,但中心对齐模式下有一些例外(参见TIMx_CR1寄存器描述中的CMS位)。它由软件清除。
-
0
: 未匹配
-
1
: 计数器TIMx_CNT的内容与TIMx_CCR1寄存器的内容相匹配。当TIMx_CCR1的内容大于TIMx_ARR的内容时,CC1IF
位在计数器溢出(递增计数和递增/递减计数模式)或下溢(递减计数模式)时变为高电平
如果通道CC1被配置为输入:
该位由硬件在捕获时设置。它可以通过软件或读取TIMx_CCR1寄存器来清零。
-
0
: 没有发生输入捕获
-
1
: TIMx_CCR1寄存器中已捕捉到计数器值(在IC1
上检测到与所选极性匹配的边沿)
这里面CCRx=4
时容易理解。但这里有个坑,就是CCRx=8
时容易被很多程序员误以为输出会为全'1'
,看图就知道并不是!所以要输出完全100%
的占空比,必须是CCRx > TIMx_ARR
。
还有要注意的是,当CCRx>8
和CCRx=0
时中断产生的时机,表面上看都是在同一处,其实有点微妙。CCRx>8
中断触发的时机是溢出时,也就是计数器计数到ARR
的时候,在ARR
的后面。而CCRx=0
的中断触发时机是计数值与CCRx
匹配时,也就是计数值为0
的前面。(这是我的个人理解哈,不当之处请指出)
向下计数配置
当TIMx_CR1寄存器中的DIR
位为高电平时,递减计数有效。参见第229页的递减计数模式。
在PWM模式1
下,只要TIMx_CNT > TIMx_CCRx
,参考信号OCxREF就为低电平,,否则变为高电平。如果TIMx_CCRx中的比较值大于TIMx_ARR中的自动重载值,则OCxREF保持为'1'
。在此模式下,0%
PWM是不可能的。
PWM中心对齐模式
当TIMx_CR1寄存器中的CMS
位不等于'00'
时,中心对齐模式有效(所有其余配置对OCxRef/OCx
信号具有相同的影响)。根据CMS
位的配置,当计数器递增计数、递减计数或同时递增和递减计数时,比较标志被置位。TIMx_CR1寄存器中的方向位(DIR
)由硬件更新,不得由软件更改。请参阅第231页的中心对齐模式(向上/向下计数)。
图73显示了一个示例中的一些中心对齐PWM波形,其中:
- TIMx_ARR=8,
- PWM模式为PWM模式1
- 当计数器对应于中心对齐模式
1
(TIMx_CR1寄存器中的CMS=01
所选择的)递减计数时,该标志置位。
图73,中心对齐PWM波形(ARR=8
)
要理解PWM的中心对齐模式,得先了解定时器的计数模式中的中心对齐模式,看这里(STM32F0x定时器之计数器模式)。
这张图CCRx=4
和CCRx=7
时是容易理解的。剩下的3个存在玄机!!
-
CCRx=8
时,有没有发现CMS=10
时并不会产生中断,只在下溢时才会产生中断。因为中心对齐模式计数器在计数时分为两个过程,从0
升到7
为递增计数,从8
降至1
为递减计数。在递增计数时并没有匹配到比较值8
,而在递减计数时匹配到了!这就是关键所在。而且这时CCRx
是等于ARR
的,不满足在上溢或下溢时自动触发中断的条件。而PWM输出全为1是可以理解的,上升过程都比CCRx
小,下降过程 并不比CCRx
大,所以全为'1'
-
CCRx>8
时,情况不一样了。因为这时CCrx>ARR
,中断产生的时机是在上溢或下溢时
-
CMS=10
与CMS=11
时会在上溢时也就是到7的那个地方产生中断,这可以理解。
-
CMS=01
时,这里又有一个坑!按照上面寄存器中对CCxIF
的描述说是下溢时产生中断,这里千万不要误以为是计数值降到1
时产生中断,看图中它是在8的前面产生的中断。这里面容易产生误区,在定时器的计数模式为中心计数时,它下降到1产生下溢事件,是因为这个计数值是与1
这个数进行比较的,当小于1时,溢出。但在PWM里面,计数值要与CCRx
这个数比较,当它从8开始降的时候,已经发现8<CCRx
,认为已经溢出了,所以产生下溢事件!(这是我个人理解)
-
CCRx=0
时,不满足CCRx>ARR
这个条件,不会在上溢或下溢时产生中断,只能通过匹配产生中断。由于上升阶段能匹配到比较值0
,所以 CMS=10
与CMS=11
可以产生中断。但下降只能降到1
,匹配不了0
,所以CMS=01
不能。
使用中心对齐模式的一些提示:
- 在中心对齐模式下启动时,将使用当前的上下计数配置。这意味着计数器根据写入TIMx_CR1寄存器
DIR
位的值向上或向下计数。此外,软件不得同时更改DIR
和CMS
位。
- 在中心对齐模式下运行时,不建议写入计数器,因为这可能会导致意外结果。特别地:
- 如果在计数器中写入的值大于自动重装载值(
TIMx_CNT>TIMx_ARR
),则不会更新方向。例如,如果计数器正在向上计数,它将继续向上计数。
- 如果在计数器中写入
0
或写入TIMx_ARR
值,但未生成更新事件UEV
,则方向会更新。
- 使用中心对齐模式最安全的方法是在启动计数器之前通过软件产生更新(在TIMx_EGR寄存器中设置
UG
位),而不要在计数器运行时写入计数器。