你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 上最强 PWM 捕获功能,1 MHz !

[复制链接]
STMCU-管管 发布时间:2021-8-25 15:15
起因. V8 e8 W! `0 u0 r% ~6 R8 R
一直想通过定时器的捕获通道捕获 PWM,这种需求是非常基本的。各种开发板例程也都有,但是精度不怎么样,能捕获的频率也不是很高。对于高频和高精度情况下明显不适用。+ V- r) A/ e6 J" z" S, B8 Y

- v' H) X$ B3 n# r, k. ?有经验的工程师会选择参考手册中介绍的 PWM 输入捕获功能,但是该功能有一个很大的限制:
+ ?9 j+ D) |* m$ Y" J% \4 `. r4 V& I) z5 j: G$ i
一个定时器有四个通道,但是只有两个通道才可以使用  PWM 输入捕获,这极大的限制了可用通道,而在有些需求中,定时器可用通道当然是越多越好。
7 a3 @7 u" @  N4 ^  @0 }
) a: b) L7 Q( c3 [所以鱼鹰一直在苦思冥想一个高精度的通用的 PWM 输入捕获程序。
% p, J0 N# Y* h9 ?  D9 w
# O' e/ r0 W6 S/ V0 Q( J
3 e  W) @, R  \7 J/ Y
领悟
' L" \/ n. z' h% q% k一天晚上,鱼鹰一边洗衣,一边思考,终于灵光一闪,既然编码器功能可以借助两组通道完成编码器,为什么 PWM 输入捕获不能使用类似的机制呢?
9 C8 e. P) F* @. i  S4 l5 n4 e4 a1 U0 K* e
手册中的 PWM 输入因为使用了 从模式 功能,才有上述限制,只要我不使用从模式,仅仅使用两个通道的捕获功能,就可以解除该限制了吧?* C! t6 _* }: b+ x, R6 V! s

8 y7 F( I+ V7 P7 P所以借助《如何高效的扩展定时/计数器?》里面介绍的知识,鱼鹰顿悟了……
: A/ y# M& {' |" Y6 e! n2 f( g  T' y% v. N
效果
) y6 I$ u4 Z& Y& a3 k( F左边用逻辑分析仪设置的输出参数,右边通过捕获程序捕获的结果。; s$ }+ l3 V2 g3 s- J
STM32F103,主频 72 Mhz,定时器时钟频率 72 MHz。 + b$ [/ I: u" |. y1 T/ K
12.png

6 J& [9 L+ M5 X; ^  w2 M' C+ U
13.png

  X- R; B: `+ F4 h' Q. _" R7 M
14.png

9 i( }, f7 [& o5 G6 T& C' |/ \% m
15.png
& l* a5 }3 N4 I5 A9 @
16.png
# G; U2 I: m( i; ]& p0 o
2 L) S/ }6 Y4 b0 `
0 @4 _% Q) {/ p0 q$ b) w
我们从上图可以知道,即使输入 PWM 频率高达 1 Mhz,我们的程序还是将其准确测量出来了。& P! w" [% L( X" S5 b0 y$ `% P# [/ S

/ l6 G/ u( X* `当然在占空比计算方面,因为定时器频率自身的原因,计算的并不精确,和实际的误差比较大,不过在这么高的频率下,只是 10% 的误差,我认为还是可以接受的。, S: f" A2 d- m2 a4 G

1 I5 y4 E# M  s* c

6 }+ B& q2 f3 e3 M3 \6 Y& e- y而频率达到 3 MHz 时,频率比较接近(4 % 误差),但是占空比已经出现了很大误差,已经不可用了(可能计算有点问题)。
$ o4 x; @" M/ ]
- f5 _5 |$ x" b3 ^8 [5 k100 K,占空比 5 % 的情况下,频率测量误差 0%,占空比误差 1%!!!/ [9 i% W# d0 C8 l
- b6 Q$ {, L6 P" |) a5 I
  Z+ x/ f7 \9 U& @8 J
优缺点
1 p0 o) i3 p/ B# {8 x  q. v+ f由于时间与篇幅原因(花了很多时间做测试),本篇笔记不会介绍捕获原理(鱼鹰要写的话,一定会尽可能的介绍清楚,所以字数会比较多,目前时间不足),主要是想通过本篇介绍 F103 72Mhz 的情况下所能达到的极致效果,让各位在接任务时有一个概念,看是否能简单通过 103 完成功能。& u' _9 S# G  N5 k+ S6 D1 ~% F3 o: F

4 x1 z$ O) t+ n! k) o( P现在简单介绍一下鱼鹰这个方案的优缺点:, q& @$ R' G' `4 \

* S& z. _) t: w  S优点:
  Q: G! u: i" x3 d6 |& ~$ C7 @1、不占用 CPU 资源,使用 DMA 与定时器捕获功能完成。  F1 y% M1 z+ L& s( s' @
    而如果使用中断的方式,100KHz 下,10 us 就需要进入一次中断,基本不用干其他事情了。一旦中断被别的代码短暂禁用,错过了捕获,那计算的结果可能就有问题了。% a* X: ~8 ^$ V( O5 K; |1 ]
2、可以分时使用定时器的四个通道,不会被所谓的从模式所限制,但能达到和手册介绍 PWM 输入捕获功能一样的精度。
  Q0 w. ]! R" ?4 [' L' m3、可以捕获高频信号(MHz),并且精度高。
5 @3 e2 _- N$ [3 _4、精度和定时器时钟频率有很大关系(F1  1/72 us),如果 F4 的芯片,定时器频率更高,那么可以达到更高的精度(可以算优点,也可以算缺点)。
8 L" |: N6 t. O* `& l3 Z. w; D0 H5、因为采用 DMA 传输 + 硬件(定时器)方式,计算的结果可以信任,不需要太多的处理(比如滤波)。
; ~  X0 O- @# c+ L6、单个通道可以达到很高的捕获率,甚至可以通过特定的算法进行实时捕获,而对 CPU 本身的影响却很小(即不占用 CPU 资源实时捕获计算)。# `& g% @- Q) j& f/ C: y& t
7、解除STM32定时器只能捕获上升沿或下降沿,而不能双边沿捕获的限制。0 A) v' v; [' j6 y, `6 Q

# S; l, J: u8 n" E- |# y缺点:
9 Z! s* x/ O! L6 t' d1、只能分时测量每个通道的 PWM,不能同时测量(如果频率很高,几十个微秒就能切换 一次测量,问题不大)。
5 b. @5 B, Y, {7 Y2、占用 DMA 传输通道,导致对应的通道的外设不能使用(比如串口)
7 u+ Q% ?; D, ~8 Y, [1 S" c3、代码很简单,但是很难理解(下面的代码计算了所有捕获,实际上只要计算几个就行,因为数据可以信任)。
/ r% K, Z8 T  a) \

  1. - D0 l. V; p! p
  2. uint32_t cal_duty_cycle(capture_buff_def *buff, uint32_t size)
    + w- b8 ?* @7 g1 x% j
  3. {
    3 Z1 y! l" n$ g+ X* `. i
  4.     assert_param(size > CCR_VALUE_BUFF);
    ; O0 F* _5 S! T' D9 I7 Q! x
  5.     ( I, K; d  R" W) v8 [
  6.     for(int i = 0; i < size - 1; i++)
    3 L+ }( x' c' k8 ?
  7.     {
    * Q* a3 H6 \9 c' K1 D
  8.         cycle_temp[(i << 1)]        = buff[i + 1].ccr1 - buff[i].ccr1; 8 W* }# S8 D" V5 @+ L/ r
  9.         cycle_temp[(i << 1) + 1]    = buff[i + 1].ccr2 - buff[i].ccr2;: K* d. [  `$ J
  10.     }* ?; u) J6 d# j7 b" k
  11.   $ h) V7 |2 R' G" S
  12.     for(int i = 0; i < size - 1; i++)
    ( D& n9 u# U8 O  k- i1 X
  13.     {9 s8 \/ f3 ^7 D6 o8 H3 Z
  14.         duty_cycle_temp[(i << 1)]     = /* cycle_temp[(i << 1)]  - */(buff[i].ccr1 - buff[i].ccr2);
    4 V' A/ M, x( |, C# _! x
  15.         duty_cycle_temp[(i << 1) + 1] = /* cycle_temp[(i << 1) + 1]  - */(buff[i].ccr1 - buff[i].ccr2);
    " ^" i4 L" H- V2 m: Z
  16.     }
    6 j, \$ l$ W5 R3 k
  17.    
    8 Z3 c, f, v" q& }7 x' ^
  18.     cycle       = (1000 * 1000 * 72) / cycle_temp[20];
    # `. A$ m+ B. s! w9 o. i6 j' g" }
  19.     duty_cycle  = duty_cycle_temp[20] * 100 / cycle_temp[20];
    8 {! V$ b/ k* M( |/ U
  20.     return 0;) Q) n0 U* h4 R! `2 N' y
  21. }
复制代码

" t* q8 V2 i& o6 ~
  f* `8 Y& r- H5 R5 @! `. \6 Y+ c/ c
: p8 N' d2 X5 V8 ?
赞 收藏 评论0 发布时间:2021-8-25 15:15

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版