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

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

[复制链接]
STMCU-管管 发布时间:2021-8-25 15:15
起因; o( V. b0 F& y- r
一直想通过定时器的捕获通道捕获 PWM,这种需求是非常基本的。各种开发板例程也都有,但是精度不怎么样,能捕获的频率也不是很高。对于高频和高精度情况下明显不适用。
6 @4 V0 I' E8 Q9 ?0 c" }
# g+ N& O. L1 }- F3 T! Q有经验的工程师会选择参考手册中介绍的 PWM 输入捕获功能,但是该功能有一个很大的限制:" C* P+ N! }' }3 O
/ w, ^) q2 g$ D) }4 `
一个定时器有四个通道,但是只有两个通道才可以使用  PWM 输入捕获,这极大的限制了可用通道,而在有些需求中,定时器可用通道当然是越多越好。
# \- F$ a6 ^+ E
, I1 q( W' x) k8 k0 `; f; ^! [所以鱼鹰一直在苦思冥想一个高精度的通用的 PWM 输入捕获程序。; c: P/ Y- i& t) q
# r% c- A* {& r1 T

! C$ J8 Q( n* J/ }" }6 {领悟1 M( ^& T% M9 b/ y: u, j
一天晚上,鱼鹰一边洗衣,一边思考,终于灵光一闪,既然编码器功能可以借助两组通道完成编码器,为什么 PWM 输入捕获不能使用类似的机制呢?; w( D: B! [- }1 J  s; m
  b& b# q$ n! f6 ?$ B) {! q5 c1 r: C
手册中的 PWM 输入因为使用了 从模式 功能,才有上述限制,只要我不使用从模式,仅仅使用两个通道的捕获功能,就可以解除该限制了吧?
! S) W( p8 S) Z, q0 x0 I
7 j, ?/ T. [' z! Y" s1 i  X! d1 U所以借助《如何高效的扩展定时/计数器?》里面介绍的知识,鱼鹰顿悟了……
3 M8 S; l, T" ^% z0 Z2 P  k) U* |/ C
效果
* {  q# w. F$ V- }# i  ?左边用逻辑分析仪设置的输出参数,右边通过捕获程序捕获的结果。: o9 ^+ V( w- @1 b: E
STM32F103,主频 72 Mhz,定时器时钟频率 72 MHz。 " M/ O& n: |/ l9 U) d! j
12.png
. D- i; Q  }) u4 r3 b
13.png
* T$ u3 Q6 W/ @4 D4 y$ P9 g" U
14.png
- t1 {) u+ X; @
15.png

8 b+ l  H+ F1 R/ }% o
16.png
; K& R* l$ R" l2 }3 s
9 I8 y$ L1 Z0 |+ y% d: z

, [& Y: R2 d# G. R我们从上图可以知道,即使输入 PWM 频率高达 1 Mhz,我们的程序还是将其准确测量出来了。
) }$ s  K6 A& ]- y
! q/ c+ [- n3 @9 y当然在占空比计算方面,因为定时器频率自身的原因,计算的并不精确,和实际的误差比较大,不过在这么高的频率下,只是 10% 的误差,我认为还是可以接受的。8 B) x3 _  b5 s& ^

5 g: ^" E; ?5 C, X4 S; ]! a' B
- K/ |' C" E  T1 m
而频率达到 3 MHz 时,频率比较接近(4 % 误差),但是占空比已经出现了很大误差,已经不可用了(可能计算有点问题)。
! p& T; R0 w4 J- A1 @0 L
9 `/ B# ^+ [1 [- _" v7 \100 K,占空比 5 % 的情况下,频率测量误差 0%,占空比误差 1%!!!
( P4 F- m: U* D1 v7 y, T+ }, l0 Z% k' V
- _0 f6 \7 c. V  J* _! h+ D' g8 [
优缺点
$ U2 m9 h0 |) J由于时间与篇幅原因(花了很多时间做测试),本篇笔记不会介绍捕获原理(鱼鹰要写的话,一定会尽可能的介绍清楚,所以字数会比较多,目前时间不足),主要是想通过本篇介绍 F103 72Mhz 的情况下所能达到的极致效果,让各位在接任务时有一个概念,看是否能简单通过 103 完成功能。
4 O4 i' `8 V$ o6 I, x
  J1 J7 A' C5 j现在简单介绍一下鱼鹰这个方案的优缺点:5 @+ p4 \  d# S  z" a9 b

! n  _% d1 R, {9 Q优点:: p) Y# J: _3 g* c1 }
1、不占用 CPU 资源,使用 DMA 与定时器捕获功能完成。
+ m" u1 e; F# f( z; G* y; E0 j) {+ I    而如果使用中断的方式,100KHz 下,10 us 就需要进入一次中断,基本不用干其他事情了。一旦中断被别的代码短暂禁用,错过了捕获,那计算的结果可能就有问题了。4 R- D4 X' F+ E
2、可以分时使用定时器的四个通道,不会被所谓的从模式所限制,但能达到和手册介绍 PWM 输入捕获功能一样的精度。
# g% d; E9 l8 L8 o6 s7 a3、可以捕获高频信号(MHz),并且精度高。- ]) T% t) e4 k0 D) T- }: Q
4、精度和定时器时钟频率有很大关系(F1  1/72 us),如果 F4 的芯片,定时器频率更高,那么可以达到更高的精度(可以算优点,也可以算缺点)。+ D' r9 l2 o) b, M5 D6 ~
5、因为采用 DMA 传输 + 硬件(定时器)方式,计算的结果可以信任,不需要太多的处理(比如滤波)。
: D; E, `$ x0 Q1 ^  [4 q6、单个通道可以达到很高的捕获率,甚至可以通过特定的算法进行实时捕获,而对 CPU 本身的影响却很小(即不占用 CPU 资源实时捕获计算)。+ `' [& f7 Y, K) @6 h3 a
7、解除STM32定时器只能捕获上升沿或下降沿,而不能双边沿捕获的限制。
2 a/ b( b' a- D/ u; [# v$ W1 r! {  X  w0 a( N4 r& E0 g, m
缺点:  J- D: z# l0 ]3 @7 l; g
1、只能分时测量每个通道的 PWM,不能同时测量(如果频率很高,几十个微秒就能切换 一次测量,问题不大)。# G, j, R  i3 c: M4 K! g
2、占用 DMA 传输通道,导致对应的通道的外设不能使用(比如串口)
, |2 w! F( M& [3、代码很简单,但是很难理解(下面的代码计算了所有捕获,实际上只要计算几个就行,因为数据可以信任)。
* i7 c! Y  x7 i6 H. a/ e9 n8 D
  1. 9 {6 b2 o5 N3 T9 S  Z+ D% F# n
  2. uint32_t cal_duty_cycle(capture_buff_def *buff, uint32_t size)" s" ]6 h! v3 v0 L2 W6 T
  3. {; k9 w( ]& j* A
  4.     assert_param(size > CCR_VALUE_BUFF);- k# q" T8 u" L+ y" A
  5.     9 \0 i8 Z, @, R! N0 n
  6.     for(int i = 0; i < size - 1; i++)
    & i9 ~  E! H& T, c3 I
  7.     {' X7 r. t. A* m( S5 D/ \* D2 ~) I
  8.         cycle_temp[(i << 1)]        = buff[i + 1].ccr1 - buff[i].ccr1;
    % U, z0 e5 L/ U# C( R5 J* S
  9.         cycle_temp[(i << 1) + 1]    = buff[i + 1].ccr2 - buff[i].ccr2;/ B1 ^% h; ~1 s, f$ \2 f
  10.     }7 k/ k! F3 t1 d+ ?) q4 \2 ~% Q# d* Q
  11.   , I. c) c/ d, B8 Q' M
  12.     for(int i = 0; i < size - 1; i++)
    4 h, ^. k# n1 {% u- s
  13.     {
    ) @+ k' D$ v% J; f& D
  14.         duty_cycle_temp[(i << 1)]     = /* cycle_temp[(i << 1)]  - */(buff[i].ccr1 - buff[i].ccr2); / v; [+ r2 P" f. G5 f9 N3 a
  15.         duty_cycle_temp[(i << 1) + 1] = /* cycle_temp[(i << 1) + 1]  - */(buff[i].ccr1 - buff[i].ccr2);
    4 z- M9 R- v/ z) `4 _
  16.     }4 ?; C" W0 X9 K8 i" i( q
  17.    
    $ p1 G: H1 t7 X9 g) p' T: g
  18.     cycle       = (1000 * 1000 * 72) / cycle_temp[20];
    + a, \( ?  c( X# i$ \3 d
  19.     duty_cycle  = duty_cycle_temp[20] * 100 / cycle_temp[20];
      m5 n% L" L$ @1 c/ w, ~* a
  20.     return 0;
    - g! A( ^  s6 e# x2 F  N0 S8 i
  21. }
复制代码

( a! Y, B6 O3 p6 ~/ z* E% X- E+ A( Z8 ]% M6 I) |
- b+ O3 d4 w; J& q1 p

$ l6 B; W7 m6 A$ [. o0 i
收藏 评论0 发布时间:2021-8-25 15:15

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版