STM32定时器中有四个带影子特性的寄存器组【影子+预装】:
- TIMx_PSC 分频寄存器
- TIMx_ARR 自动重装载寄存器
- TIMx_CCR 捕捉比较寄存器
-TIMx_RCR 重复计数寄存器
其中ARR、CCR寄存器带预装载使能控制位,PSC、RCR无预装使能控制位,所以对于PSC/RCR实际寄存器的数据更新只能通过更新事件实现从预装寄存器数据到影子寄存器的拷贝更新。
对于ARR/CCR寄存器,当关闭它们的预装载使能位时,用户修改预装寄存器的数据后会立即被拷贝进影子寄存器【实际寄存器】,否则,修改过的预装寄存器的数据只能等到下次更新事件 来完成从预装寄存器数据到影子寄存器的拷贝更新。
这里分享三个跟影子寄存器的预装特性有关的案例,以加深大家的理解。
【案例一】
异常情形:某客户使用到 STM32芯片TIMER1和TIM2,其中使用TIM1做PWM波形输出。使用PWM模式1,向上计数模式,每次在定时器上溢中断里调节CCR寄存器的值,改变波形占空比。
但他发现,当打开定时器2并使能定时器2的中断时会导致TIM1的PWM输出异常的现象。有一定几率出现尖窄脉冲现象。在正常占空比之后出现一个极短的小脉冲。测试中,CCR的比较值读出正常。关闭定时器2则输出正常,未捕捉到小尖脉冲。
【下面的第一个波形是初始波形;第二个波形是修改后的输出波形;第三个波形是计数器计数变化示意图】
先大致分析一下条件及现象:
1、经了解,他关闭了CCR寄存器的预装功能,即修改CCR的数据会立即拷贝到实际影子寄存器而发挥作用;
2、他采用PWM1模式的特性,向上计数,输出极性高有效。这个条件下,当CCR的值比计数器值大时,输出高电平;当CCR的小于或等于计数器的值时,输出低电平。
3、它在更新中断里随机动态修改CCR的值,如果没有其它中断存在。发生TIM1溢出中断时,立即响应并修改CCR的值,由于CCR的预装载功能关闭,所以修改立即生效。下一个周期的波形按新的参数运行。
4、如果有其它中断的存在,且TIM1的溢出更新中断不具备抢占能力,具体到这里,如果TIM1溢出时,TIM2中断正在使用CPU处理事情。那么TIM1中断请求就只能等待TIM2中断事务处理完毕后才有机会修改新的CCR值。但这个等待过程中,TIM1的运行及PWM输出并不会停止,依然按照原来的参数在运行。如果新调整的CCR值比之前的CCR值要大,当TIM1的中断修改完CCR值时,输出波形又刚刚变为低电平不久, 由于新的CCR值比当前计数器的值要大,结合pwm1的输出特性,这时就会出现了尖脉冲的问题。
假设TIM1开始的pwm参数是CCR=100,ARR=300.当TIM1发生溢出中断请求时,TIM2正在处理自己的中断服务程序,而TIM1的中断又不具备抢占能力,假设知道TIM1的计数器记到103时TIM2才释放CPU,显然TIM1的PWM输出刚做完从高到低的跳变,如果此时TIM1的中断服务程序里将CCR的值改为200, 并立即生效。这一改,CCR于计数器的比较结果马上改变了,即在计数器记到200前都是CCR大于计数器的值了,此时对应的输出应该是高电平。所以,刚跳下来的电平,马上又跳高,这时就产生了一个低电平的尖峰脉冲。
当然,如果新修改的CCR值比当前计数器小,那就对当前周期的输出不会有影响,因为在溢出前一直是计数器大于CCR的值。
所以这个尖脉冲是时有时无,其宽度与TIM2释放CPU的时机以及TIM1本身中断服务程序处理时间都有关系。
处理办法:
1. 开启ccr寄存器的预装功能,让其在下一个周期生效发挥作用;
2. 调整TIM1的中断抢占优先级,让其抢占TIM2的中断。
【案例二】
【第一个波形是初始波形;第二个波形是修改后的输出波形;第三个波形是计数器计数变化示意图】
这个案例跟第一个有点类似,这里是在比较中断里动态修改CCR寄存器的值。CCR寄存器的预装功能是关闭的,即修改的数据立即生效。也是PWM波形里偶尔夹杂尖脉冲的问题。
【案例三】
基于ARR寄存器的预装功能的开启或关闭,修改ARR的数据看看相应的PWM输出情形。前提条件还是UP counting + pwm1;极性选择:高有效 。
特别注意下图中的第一种情形。即在关闭ARR的预装功能、向上计数模式的情况下,如果新修改的ARR值小于修改时刻计数器的值,计数器将持续计数到其满量程值,对于16位计数器就计到0xffff,对于32位计数器则计到0xffffffff才发生溢出。这点要特别注意。
前面跟大家分享了几个跟影子寄存器的预装功能有关的案例,希望大家对影子寄存器的预装特性有更深的理解。