查看原文
其他

PWM输出第一个脉冲宽带异常的话题

Miler 茶话MCU 2022-09-10

我们在使用STM32定时器做PWM输出过程中,当借助示波器或逻辑分析仪查看波形时,有时会发现输出的第一个PWM脉冲跟后续的输出脉冲不一样。比方像下面的输出波形,第一个脉冲的高电平要宽于所有其它后续脉冲。



对于这种情况,有些应用是不太在乎的,但有些应用场合可能就不能接受。那这个问题是怎么产生的?有没有办法解决?


产生这个现象的原因简单点说就是在于定时器比较输出模块的工作与定时器计数单元的工作具有相对独立性。使能比较通道的输出功能的操作与使能计数器的操作有个时间差,其长短往往跟用户处理代码有关。


我们知道,STM32的高级定时器或通用定时器,可以大致看成由四个模块组成,分别是主从控制模块、时基单元、输入捕捉模块、输出比较模块。下面截图是STM32F4系列高级定时器TIM1的功能框图的一部分,这里没有将定时器的主从模块截取进来,只保留了时基单元、输入捕捉单元、输出比较单元。



这三个单元既可以相互配合协调工作,也可以各自独立工作。比方说,输出比较单元的工作并不要求时基单元的计数器工作,换言之,即使计数器不被开启计数,输出比较单元依然可以根据默认配置或用户的有关输出配置而发挥作用。


我们不妨结合一个具体实例来看下。假设定时器TIM1的计数模式选择向上计数模式,让通道CH1按照PWM1模式的规则实现PWM输出。配置好ARR和CCR1,极性选择高有效,即OC输出与OCRef参考信号保持同相。


对于定时器的初始化,我们一般会先对时基单元的相关参数做配置,比如时钟源、ARR,PSC等,然后对比较输出功能做配置和使能。当完成比较输出的配置及使能后,即使此时没有使能时基单元的计数器,比较输出单元就发挥作用了,即它会结合比较输出配置和CNT与CCR的比较结果在OC端输出相应电平。


根据上述配置,若CCR大于计数器CNT的值时OC端输出电平,否则输出电平。若用户没有专门对CNT寄存器进行赋值,芯片复位后,它的默认值就是0,显然CCR的值要大于此时的CNT的值,自然此时OC端就输出高电平。如果此时计数器还未被开启,这个高电平就会保持到计数器被启动,并延申到后续的PWM输出动作中。即这个高电平会跟第一个PWM脉冲的输出连在一起。若刚好碰到第一个PWM脉冲首先是输出高电平,这就导致第一个脉冲的高电平宽度要宽于后面其它所有PWM脉冲的。


下图第1处乃通道OC功能配置完成被使能的时间点,第2处乃计数器被启动时间点。

在跟上述相同模式和极性条件下,有没有办法消除第一个脉冲的多余宽度呢?


办法是有的。既然OC通道被使能后,其输出由CCR与CNT的比较结果和PWM模式决定,这时我们可以考虑在使能OC通道之前手动将CNT的值进行修改,让它等于ARR或0xffff【若是32位计数器就是0xffffffff】,此时CNT的值不可能会小于用户配置的CCR值,就这样通过改变CCR与CNT的比较结果达到改变OC端输出电平之目的。


比方,如果你用STM32标准库写的话,你可以在下面红圈的那个地方加一句:【arr对应着时基单元中ARR寄存器的值】

参照上面相同定时器配置【向上计数模式、PWM1模式、极性选择高有效】,下面基于Cube库使用STM32F4的TIM1的通道2进一步做个验证测试。


使用CubeMx配置完成生成初始化代码,需添加的用户代码比较简单。如下图所示。其中方框里的延时函数代码是用来模拟比较输出使能与使能计数器两个操作间的间隔,以便观察效果。

基于上述代码,我们通过示波器可以看到第一个脉冲明显宽于其它后续PWM脉冲。【如下图所示】

在上面代码的基础上,我们在使能CH2比较输出功能的代码前添加一句修改CNT寄存器的语句,令其值等于ARR或等于计数器的满量程值。下图中椭圆圈内的代码。【若把CNT值改成等于ARR的值,效果也一样】

然后再进行测试,第一个脉冲也就不再异常了。【如下图所示】

最后小结下,这个现象只有在使能定时器通道的比较输出操作与使能计数器操作存在较为明显的时差时才可能发现,而且它还跟所选择的PWM模式有关,上面只是针对向上计数模式、PWM1模式做了分析和分享,当涉及其它应用模式时可具体问题具体分析,只要弄清原因了也就不难灵活应对。


==========================

往期阅读话题链接【点击阅读】:

1、定时器输出4路不同频率波形的应用示例

2、基于STM32H7片内FLASH编程失败的话题

3、基于STM32H7 DMA传输的SPI 应用示例

4、STM32 IAP应用中的几个常见问题

5、一个跟初始化顺序有关的异常话题



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存