PWM输入原理解析

电子说

1.3w人已加入

描述

介绍之前,首先介绍一下 STM32F103 TIM 的一些相关特性:

  1. 无法使用外部引脚中断触发 DMA (有些型号可以)
  2. 无法使用 TIM 同时捕获 上升沿和下降沿 。你在库里面看到的宏其实在使用时受到了限制,高级定时器1、8,通用定时器2、3、4、5都不行,而一般103 就只带这些定时器。

PWM

PWM3、高频信号输入时,中断进入很频繁,如果是 100 K 频率,你需要 5 us 进入一次(高低电平各一次,还是在占空比为 50 % 情况下,其它占空比条件更为苛刻),如果采用中断处理方式,你必须在中断中完成很多操作(清标志、计算、翻转极性等),同时你需要保证这两次中断不能被全局中断禁止,或者被高优先级中断打断,否则,你得到的可能就不是一次脉冲的高电平了,这样你的占空比、频率都将计算出错。

正因为有如上问题,而捕获 PWM 脉冲又是比较常见的功能,所以需要一个高效的捕获程序完成该工作。而鱼鹰今天介绍的实现原理我认为就是最高效的。

100K 频率误差 0%,占空比误差1%!

在嵌入式中,100 K 频率已经算比较高的了,当然是在关注占空比情况下,如果只关注频率,那么可测量的频率将更高。

可能有些人会抬杠,说,干嘛不使用 FPGA。鱼鹰当然知道有比单片机更有效的捕获器件,因为我自己买的 逻辑分析仪 (想买这个的可以找鱼鹰预定,可以给一定的优惠,预定人数需要10个以上)就可以捕获很高的频率、精度,但问题在于成本,在于有必要吗?这个逻辑分析仪可是几百大洋啊。

闲话不多说,鱼鹰首先介绍一下该捕获方法的基本原理。

很简单,就是利用二进制溢出特性实现的。(2038问题-动图)

PWM

这个特性鱼鹰在笔记中也多次介绍了其中的应用,比如无锁队列、扩展定时器、编码器、延时等,今天就再加一个应用,PWM 捕获(本篇笔记不介绍这个特性原理,可以看历史相关笔记)。

可以说理解了这个特性,在各种整型数据处理中如虎添翼,再也不担心数据溢出的问题,反而要利用该特性完成一些骚操作,比如今天 PWM 捕获就是如此。

另一个绝技就是使用 DMA 了,这是它高效可靠的原因。

首先我们看看定时器的构成框图:

PWM

上面标注部分就是为什么 PWM 输入模式只能使用通道 1 或通道 2 的原因。

这里我们以TI1作为PWM输入,两个捕获通道同时捕获 TI1 为例说明。

基本配置如下:

  1. 捕获通道 1 触发 DMA,同时设置 捕获上升沿 ,这样,只要上升沿触发了,可以自动完成捕获并DMA传输至用户缓存。通道 2 下降沿捕获 ,不触发 DMA。
  2. 配置DMA,传输外设地址不是某一个寄存器,而是 DMAR,同时设置传输数量,这一定是 2 的倍数,因为一次需要传输两次,32 位宽度。
  3. 因为需要传输两次 CCRx,所以需要正确设置 DCR 寄存器。

以上配置就是整个功能最为关键的部分。如果你理解了下面介绍的捕获原理,你自然知道为什么需要这么设置了。

我们首先看看 PWM 捕获时基本工作过程:

PWM

另外还需要了解 TIM 一个很重要的DMA 传输特性:通过配置寄存器,可以一次触发,多次DMA连续传输,这个特性在这个功能中也被用上了。

PWM

PWM

如何利用这个功能呢?一般我们配置 DMA 传输时,比如串口,一般外设地址就是 DR 寄存器。而如果我们想传输 TIM 的捕获值,我们可以设置成 CCR1 寄存器的地址。

这样也可以正常传输,但是只能在触发时传输一个寄存器的值,如果需要把两次捕获值都传输,那么就需要配置两个 DMA 通道完成,但这里又涉及到了两个 DMA 通道同步的问题,因为你肯定希望每次采集的两个数据都属于同一个脉冲。

所以 TIM 用了这两个寄存器解决这个问题,通过 ** DMAR 中转** ,就可以完成一次触发,连续传输两个 CCR 的值。

想必看到这里,你应该大概知道该捕获的原理是什么了。

PWM

这里鱼鹰再结合上图描述一下。

初始化(定时器、DMA、GPIO)完成后,定时器就准备好工作了,一旦有一个脉冲输入,上升沿触发,此时因为设置了 DMA 触发,同时设置了连续传输两个寄存器,所以它会把当前的 CCR1 和上一次捕获的 CCR2 (下降沿触发)传输到用户缓存,这是 两次 DMA 传输 ,所以DMA的计数器会递减两次。并且 CCR1 的值比 CCR2 的值大 (不考虑溢出情况下,并且差值情况下,大小没有意义)。这样,上面的三次触发,我们可以得到三组捕获数据。

PWM

通过 (uint16_t)(CCR1 – CCR2),我们可以得到 低电平 ,而通过两次CCR1 或者 CCR2 的差值,我们可以得到 周期 。这样计算频率和占空比就不是什么难事了。特别需要注意的是,三次上升沿捕获期间,定时器不可以产生溢出现象,这可以通过定时器分频实现。分频系数越小,分辨率越高,但越容易溢出。

这里要注意的是,如果频率比较高,建议多测量几组数据,然后取后面几组数据进行简单平均或中值计算(具体根据捕获值来确定),这样准确度更高一些,因为刚开始可能因为初始化的缘故,导致意外捕获,这是可能的(刚开始不确定可以测个 64 组再说)。

另外如果输入 PWM 频率或占空比会 不断变化 ,也需要根据情况多测几组(或定时测),并进行简单处理,这样不容易刚好捕获到变化的脉冲,保证脉冲计算的可靠性。

总之,怎么去让你的程序更加可靠就是各位道友的事情了,鱼鹰只是提供一个解决思路。另外鱼鹰不准备提供源码给各位道友,自由发挥吧。如果确实有需要的话,在本篇文章更新前的时间里,道友有过赞赏或者留言被置顶或转发支持的情况,那么也可以主动联系鱼鹰,鱼鹰可以给一份参考程序,仅供参考。以前没有的就别找鱼鹰了

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分