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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。7 J, V# k  P8 ?2 H$ ^
: b7 D/ }( I! z/ T
即使用输入捕获来统计。
' R9 |- j. [( }7 {$ ~! a$ ^1 q
0 J8 L! q4 o. C4 W5 l- ?
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。
3 C2 L# ~/ g0 Q5 R  _# S2 ^4 s8 h9 @( c6 d0 g$ q3 H
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)) @# E  P, f: `3 R2 e

9 b& u) c' G% Z3 J1 z4 u; b" i
微信图片_20240529171352.png
' h) D5 S* y& e( Y) I0 ]
, E* e+ |6 u: Y9 x* E2 r这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。. W0 ^* E& Y' N" R. K. K& P$ @
& c! M5 J0 |1 s$ v0 X; ~
微信图片_20240529171348.png 4 s5 Q2 q4 c( {% J
" ]* D0 p; z6 T+ |/ {( L9 j
这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。
' j: ^1 n) Q" D) }, S
% W" f$ K1 q8 E1 E* k 微信图片_20240529171343.png , i7 U# j. t2 l6 e  a
7 K) ^% ?6 _! I$ t
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
4 t: c! F3 x' g5 ^; W9 O( A5 Y" `. i. M; U2 F$ o0 ~% c  o
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)
8 _" J7 Y2 ]. X* o/ [
7 K: h, y7 o$ D! p% G# a
微信图片_20240529171339.png 1 D4 ~( w/ O8 U8 D6 o  h' v0 B: r

: _# m3 W, K% h5 [& l
4 r! m2 ?$ w$ ~. ~5 x5 G5 F
开启定时器中断。
$ t) N( L. l, O
7 j7 q! L4 D/ w( q& ]/ j2 O
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。+ s  I* ^) v6 M7 e1 v7 j

2 O7 |; W; I. D
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。
5 G, m: ?" N- P$ w- ^& D& h3 B% ?( ^7 u! z- y, h
这里分频系数也不能太高,我就干脆不分频了。$ l: U/ U( J% x7 M4 o9 a
; N8 c5 z4 M; m1 I' }
因为等会我们会清除计数器' W8 ]) Q' b3 y/ B- _2 U

! z7 ]  V& {* b! }0 ~
  1. struct Pre0 I) D$ @- [5 n# `. [
  2. {
    ( G" E7 x2 J+ W8 y0 z/ l, u- R
  3.   float HighTime;//高电平时间' ?- g: n3 g( }+ p; N
  4.   float LowTime;//低电平时间
    % b" T3 ]& H* _+ R* G* k
  5.   uint8_t CapStatus;//计算是否是第二次捕获
    " w& q: P- k- l3 f) Z( W, b
  6.   float Frequent;//频率值# i% |; k. k! Z+ b% [! R# Y2 {
  7.   float Time;
    9 ]; P2 c( C( b* \( h$ e
  8.   uint8_t EndFlag;//捕获结束
    # M0 [7 ?& O  R) |: ?+ o; N+ v
  9.   float Duty;//占空比
    : r$ w8 c( G( v# I# g
  10. };
    6 M- x1 I, Z0 J5 C1 K( a9 ^6 I: S

  11. 9 H! a5 k# s! ?* H- _! M
  12. 6 G' _, |' o0 ~6 `
  13. . \, u- l/ l% t- H- i* ^4 s

  14. ) C( {3 f4 s# m9 Q! B1 Y2 S
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    - V% b1 ?, c9 s5 \% L6 X8 z
  16. {* ?2 \6 n8 J/ h/ s
  17.     if(!pre->EndFlag)
    " i5 o4 l5 N3 s6 t8 H  K
  18.     {4 l5 \; m6 H( W  M( [9 [* S/ c
  19.       if(pre->CapStatus == 0)        //第一个上升沿% A& p- q" R& t6 N- T
  20.          {
    2 z7 G- G4 \% \; ^& Q" g7 l' m& V, [
  21.            pre->CapStatus = 1;* c8 u- x+ l& _. p$ T, u
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
    5 v4 _, a9 K" y' |
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
    + f( }6 C6 [/ n+ e  h+ b$ e
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
    ( q0 r5 V8 E/ S3 v  Z1 z
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿8 H3 [2 |* f4 z
  26.           {
    + n2 m2 M2 T4 u' F
  27.              pre->CapStatus = 2;
    ( H* H7 `9 f4 u1 d; V5 q
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置6 x3 c; d0 _4 x" u4 G# F0 E
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发6 }' x7 N% z4 Z  E' f1 [
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿7 O2 ~; s4 J  f1 H1 O/ R
  31.           {3 A4 H8 R/ m$ k+ p, T
  32.           pre->CapStatus = 0;
      c8 N) ^! I* Q# F! A$ N/ F3 Z: m5 @' P4 E
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);
    ; P& f: m) A2 ~7 f  D
  34.           //计算频率2 r) c& O; P* N8 T8 A  v
  35.           pre->Frequent = 1/pre->HighTime*100000;
    0 Q8 Y8 L( F2 w& N
  36.           //计算占空比( n9 T: |7 p# F# N
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);, s( M- T! r5 [5 U, m/ X
  38.           pre->EndFlag = 1;
    , p. f& C( w) m: t
  39.           }
    - }2 n# ?! ]$ R  f( o
  40.     }
    ; ^) A' M9 H% _; o8 S1 m
  41. 1 B2 W: X( t# u) y4 @  F' Z

  42.   T9 d1 J7 \' J3 l6 R
  43. }
复制代码

5 v* H: ]' z, Z! m3 b! @+ H我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
" O$ J( Y+ q0 {% g
3 n* e3 }- R8 f+ N* K; d
主要统计两个上升沿之间的时间。
: s, F  K8 e5 m& h# p+ O4 t! t( H& g3 a4 m7 g" @' Y0 m7 P8 k
  1.     HAL_TIM_Base_Start_IT(&htim16);
    8 y8 z7 [, E* d' X
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
    7 S) p, {4 N: F" g
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断0 R4 {& \. P3 n7 U# @1 k1 \
  4.       HAL_TIM_Base_Start_IT(&htim8);
    5 ~1 l5 ~' E9 Y/ w+ O
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    7 H: j# U3 z. R, |- p6 N
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码

' k! Q' y; R+ a9 j( C" ]# r开启定时器计数以及使能中断。0 i, ~, v" Z+ D9 i
" E+ @% z  ?" y3 I0 v8 P! n, `4 Q$ }
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)8 B2 L7 r  \9 |$ o
  2. {2 ]0 p/ P# B$ g& m7 R6 o
  3.   if(htim==&htim8)4 ^% ]% A4 F# r3 j
  4.   {4 F+ W2 G, y3 B7 @
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    # v' a* H4 R6 A% i8 B0 J- N
  6.   }- x  e4 P4 a8 W% W8 k# S
  7. }
复制代码
: |7 r7 V. G& F& h6 e
输入捕获到频率检测。
9 Z1 V- p- s6 m: T0 m& g7 T  `9 o- A, z- l. s$ ^* L) x" f
  1.       if(pre1.EndFlag)  U; B+ d: ~7 i( b
  2.       {
    " N( C& a* A6 c3 n+ V
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    + ~7 L" j0 E/ M$ J& z8 W3 T' q
  4.         LCD_DisplayStringLine(Line4,pr);
    $ O. G- b1 z, D: w! J- }* L4 v
  5.         pre1.EndFlag = 0;
    ' \7 ?- j1 f  G1 e4 M: K! d
  6.       }
复制代码
. Z0 J9 T1 c! P( L7 c( P
如果检测结束则打印频率值。8 T+ q9 i4 g: E1 \
0 X- n. B! T! T- M" h5 ]
微信图片_20240529171336.png
5 j- e. }$ U+ X
) {- E) D+ k( k% r) W$ a- ?2 N$ B$ S% c) o% S! b$ f
微信图片_20240529171330.png
9 P0 c3 Z0 {) Q% \, k
5 A7 K: Y6 k9 i- k" k5 ^
3 s" q  ^/ `5 o. ~! r1 q我们可以看到理论最低频率为716.41HZ5 b8 H- K( X8 L& n6 s" c3 k0 @
" [% t" t& \# i6 }+ a, Z& i  z
微信图片_20240529171326.jpg ) ?  F) u' t2 L/ j, y) v, U/ I
- M( F3 ~% \! i" ?; f
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。
% ~0 U" ^4 i" i6 |
  Z; b& e  o6 [/ m4 P' W7 F2 G4 o
& e) V( @- w* q8 g4 |

/ |$ S; a$ n  c( \9 l9 f转载自:电路小白
) t$ k+ h8 Z' I& T如有侵权请联系删除
' i: l' a# w5 Z6 ?. o

2 i$ A9 r2 Y8 E6 W9 N0 w+ p# T. q$ @( f! b/ ?% m- ~1 x
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似分享

官网相关资源

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