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

基于STM32CubeMX输入捕获测周法检测频率经验分享

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
, j2 B$ n7 @; o' E1 S1 u0 B4 ~; }1 T! H% A" o
即使用输入捕获来统计。0 z6 a' F, Q) \5 Y- }) @' B, S
1 f! }+ X$ O: Z9 N
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。6 M- a- h8 n! s4 {. j4 Y% `  t
+ b( M+ r; E& O
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)# t: k1 Y% d2 {, c( q" N3 \

4 g! s1 G1 T$ _# A0 M% I
微信图片_20240529171352.png / f' ^  j$ d" K9 w: u% X
  j7 l0 z5 l+ P' R2 M+ g
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。: X1 ~0 r4 l! Z" j' v

+ i0 O' c: }! C$ u( U4 a4 s 微信图片_20240529171348.png % w- O2 S: B$ _1 a$ z

' ~3 ^/ s3 _3 F8 W这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。6 h. b. Y* [( F5 E4 D5 r

/ m% Y  M, I9 f, F% N 微信图片_20240529171343.png
# ]9 u2 Z9 e) K. T5 M0 `
$ p: x, h9 |, J
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。3 U2 g7 q( }/ l& Y- r+ l; j

; J7 q6 H2 p6 }4 O# t
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)* B# u( l5 }2 Y$ P
$ v+ i' ?! |% N6 t  W
微信图片_20240529171339.png $ b1 o; x- k/ l2 q

! _& P* F5 _* V- ~6 K  ]
+ O% ]! v# [% m
开启定时器中断。5 y& M" h' s2 ~- ^! R/ m# D5 |
( k" m9 z) k# v3 q% n
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。
: a' t% h% H2 ?" t
( x0 t6 ^' N, h
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。2 P; Q  L& t. q9 K% _* [
% k. S! W$ W; r. _
这里分频系数也不能太高,我就干脆不分频了。# v* O  w% }& R; k$ b1 R" b- |

, J' v6 w# x$ Q4 K5 w8 z5 y
因为等会我们会清除计数器
! Y) J) a1 d- c# U  o* M+ f& _
  1. struct Pre
    4 M( |) ~* _  q3 D) K
  2. {
    / s& ], W- T* ]
  3.   float HighTime;//高电平时间* f; ?9 j: `" @9 v( |4 q
  4.   float LowTime;//低电平时间5 e- R5 F3 ^5 F' d. `
  5.   uint8_t CapStatus;//计算是否是第二次捕获, g# W& @( W& q1 z
  6.   float Frequent;//频率值
    0 G! A3 A0 \3 Z% v
  7.   float Time;
    6 A+ y# g- n$ M
  8.   uint8_t EndFlag;//捕获结束8 d- ]: u! Y' z! W$ M6 |0 i% P* G
  9.   float Duty;//占空比& ^# f6 L! S0 {" o
  10. };; V0 E; P6 |# @8 _

  11. ' |1 \3 _4 T4 X9 w  W

  12. ! J) A2 k# ^# B
  13. . k( m! E. R, _' Z/ P
  14. 6 a# @) U+ j5 A2 ?8 V: R, B8 X; [; W
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    * U( D( o; m. K* D& N; N
  16. {  U7 J. x* Q4 [) ~8 y: R: e' n
  17.     if(!pre->EndFlag)
    ! e$ E9 v# s1 x7 P/ W! R2 [
  18.     {# W" k* r( c+ I0 |
  19.       if(pre->CapStatus == 0)        //第一个上升沿" C5 Z: f2 R# X  ~* J( a
  20.          {
    1 W0 u6 g0 ?. ?9 M
  21.            pre->CapStatus = 1;4 X3 X8 o9 p, ^4 x3 P! n4 x
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
    + W: |3 h. n4 F! h8 a$ p
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值% n+ Q4 _7 R( o' @# j
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置  W+ c9 S# w( a1 T
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿/ U- a4 Y7 j. S( S. V( f
  26.           {) b3 M5 B' b+ F6 P
  27.              pre->CapStatus = 2;
    / x0 Z8 F  }* _) L6 i! ]1 G
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置' q  b5 T1 A# b; H2 H
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
    , C' I. U! u7 F5 D3 R
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿
    / S) m$ ]1 K: _( _- A' N% \
  31.           {; h7 c; ~5 p( u' n$ A7 G
  32.           pre->CapStatus = 0;! S. P7 l1 O3 C! S3 v, i. X/ c
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);; }: D) Y- G# q/ G9 l4 n$ B! P
  34.           //计算频率
    + D5 _- |- A2 x
  35.           pre->Frequent = 1/pre->HighTime*100000;
    $ W0 t. m' z" [) J$ Y" d9 |
  36.           //计算占空比& D; W9 ?  \( b; W
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);3 A/ W/ f7 a5 M0 }9 a. q- \1 b8 A
  38.           pre->EndFlag = 1;& X1 C- m4 ^( e% |( G: s9 M  Y7 q1 P
  39.           }4 g# _0 b2 V, A' o
  40.     }
    9 P! X7 ?5 P9 `" w8 I* j
  41. , `0 y( M& s- U( U9 h
  42. ! Y5 i; H5 y3 }; c$ \. T
  43. }
复制代码
: y5 ?# l. e5 L/ a9 W
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
0 y# w4 w/ P9 t! S8 P( p4 H% \4 o/ E5 ~& X# Y3 i9 m
主要统计两个上升沿之间的时间。3 i0 E: ?2 U2 W7 V8 h- l

# O+ ?( S4 D3 g) P1 ~* @
  1.     HAL_TIM_Base_Start_IT(&htim16);0 J$ o5 f# U8 ^  o* V% Y- J8 E1 i
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);4 J6 _9 s7 G3 s
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断
    5 K/ [. Y( _, q- G) q
  4.       HAL_TIM_Base_Start_IT(&htim8);
    5 r9 a! O0 a6 U+ p
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);; b. r+ T$ t9 O! X
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
2 K5 u8 ~8 g- {( ~! S# l+ U- A6 \/ F
开启定时器计数以及使能中断。
' r$ R' V4 t+ e
+ [- ~6 r5 T  u0 N2 V& \: H2 c, p
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)  H# ~3 S3 x$ I! x. c
  2. {
      E8 B5 O5 q* g7 c9 v
  3.   if(htim==&htim8)1 a+ |! c1 K% N% r% M6 W# M
  4.   {
    8 m! f1 U" X1 }7 s, V  s2 T
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);. C, v$ k1 @9 I- g" N
  6.   }9 j# O0 V6 ]) P- ^1 v; r# M. I
  7. }
复制代码

6 o# y) p6 j6 G" t2 N输入捕获到频率检测。9 Y  {, B4 n! S7 D  ?
: S% H' ^9 q+ k4 x' n9 X
  1.       if(pre1.EndFlag)
    " |- ~+ @7 A% o- n' X
  2.       {
    4 v( U, e" E! _6 X, w! s
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    5 K( M% i5 Q6 M
  4.         LCD_DisplayStringLine(Line4,pr);
    $ v: K& X9 C4 f. I& @2 M0 M
  5.         pre1.EndFlag = 0;
    ! i0 O0 d! O3 q0 U( [8 b4 z
  6.       }
复制代码

6 Z7 r; m2 c( Y* b# j! {+ C0 X9 S如果检测结束则打印频率值。
# u1 I" C5 @1 v8 h# j' ?; I, _; `* Y1 _* Q
微信图片_20240529171336.png
) G2 H$ M" U: }; l7 U1 K% Q
0 R7 k5 [9 [2 l# O% i7 m. y
& K% G3 M( T- l) F 微信图片_20240529171330.png # O1 V2 P( L2 P) _  {1 k/ o

5 [) n5 T  C2 H  J& i3 v; B  \. H  ?  {
我们可以看到理论最低频率为716.41HZ
# e  X1 }! J. }0 e' r
2 L) v$ ]5 Z% \9 M) w8 o 微信图片_20240529171326.jpg 4 E( T/ {6 y( `
+ R, o3 T8 @* y! c$ p* c* R- V) x
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。5 _& R/ K+ }% ^& v9 v5 F; w. I. ^

* U& ^2 P7 S9 b/ ]+ A: ^" F% d

& ~  O  E, B) q  j" k, f) E# W( I% N7 }& T& N' l! h" j
转载自:电路小白$ p5 K: k. v  w# y6 N6 n  B* v( q
如有侵权请联系删除" p0 ^" l" z" z
; ~8 X- G# J6 u/ L0 _2 H
1 F* w) j3 c) s' a7 H' F9 O- m4 [
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似分享

官网相关资源

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