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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
( @4 V! ?7 U) M0 u7 k1 K
4 P  x+ {) w, n+ f; d9 c, s2 K1 _
即使用输入捕获来统计。
) x. n: }5 D4 ]
, O  L4 \* y9 I. m8 X9 U
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。
* k# i; z% k  q! I5 L, F( m& ]
2 V6 B# i. G/ M: {9 T
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)0 {0 B3 _  b$ E. X$ O# w, }
+ k& |! J1 Q9 G( X5 P4 d
微信图片_20240529171352.png
2 |8 ^* `4 }* t% |% F% J! ]& K  U- @! F9 V0 y8 h& ^
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。
0 h/ N6 p1 [- x5 Q0 G
' Q% ^, R4 h% }* v, C5 B 微信图片_20240529171348.png
$ X' s7 O% t, X7 n" G; d  p# }

- `- T3 u) D% W: m, a( B- C这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。8 \" W5 |& \3 s" v. f8 J/ A

' l# W) }; X/ m 微信图片_20240529171343.png
! q  d6 T0 g- x/ K8 w

3 Y( m! q( \5 p! b$ p触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
' c. O: ]8 m2 a! v' c0 X1 \7 h2 Q, Z
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)6 q' O+ K$ m4 n- I/ x
/ f/ V! U: U. }. `8 F
微信图片_20240529171339.png
( {, y/ x% f3 a: K0 T) T* j+ j$ A. ?5 T& a2 s+ q

! `5 s5 `3 W5 |/ z开启定时器中断。9 }8 v) o5 |  |% r/ q- }) `- g
$ ]! X5 A+ B5 A' ^
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。* s: c- N( a! O1 F
" k) D. e7 @8 l* g7 f2 \" q& o% }
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。
6 A# D7 }, _, b2 [! e7 {
" w: \& `1 X0 u- G; e% P" D8 N
这里分频系数也不能太高,我就干脆不分频了。" }! w& d' ]( ~. {7 w) Q

# Q# p) ?6 j, A" U6 I
因为等会我们会清除计数器# h3 N- C+ U/ E. P$ y9 t, ?

1 E; |3 i0 p+ E7 p& r0 h
  1. struct Pre
    ; G' l$ Z3 Z; A3 v
  2. {
      z: ]9 h5 w- B0 d7 f+ M8 Q7 L$ u
  3.   float HighTime;//高电平时间
    2 g- I; D/ d/ g
  4.   float LowTime;//低电平时间0 {2 R( d, D$ L' B
  5.   uint8_t CapStatus;//计算是否是第二次捕获& U' p9 j, J9 J5 ]
  6.   float Frequent;//频率值
    2 D/ J5 d1 G1 b0 _; D! P% R: n" F5 a
  7.   float Time;3 P+ y: h( i2 ?/ h& k1 `
  8.   uint8_t EndFlag;//捕获结束8 o3 t: u: z* }) h$ v. c
  9.   float Duty;//占空比3 Z& n/ K. p; t) z& n
  10. };  u  e5 p) b2 X' X
  11. 2 H+ ]5 f8 L5 b* ?& F  b- u

  12. 5 t( f0 L  M% c5 \8 R2 r
  13.   y5 J7 ~) B% a2 ~& c
  14.   X( q2 K0 P% A
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    4 s1 e' U6 z: B' d4 r% \
  16. {
    5 Q" X/ ^- X% X* j) F( K
  17.     if(!pre->EndFlag)
    0 k/ t8 m# c) P5 C
  18.     {
    2 p  o, d. ]+ J; u2 B
  19.       if(pre->CapStatus == 0)        //第一个上升沿
    4 f! f  C1 a; N# j9 W
  20.          {) ?$ ]8 U2 }# R& F' R! X' N
  21.            pre->CapStatus = 1;- u# G+ I# T) J( P/ [- P
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
      y4 L: {4 T8 ^. L" M: }: }0 g
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值9 s6 Q2 e* b$ w- N, l& O! c7 y
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
    ( E7 B3 G. Z2 Y* n; T
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿0 k! s  m( ^- w$ F9 [2 o: W
  26.           {; m: [9 q  A- L8 L
  27.              pre->CapStatus = 2;. W! _% Z! @. Q( @
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置3 w, N6 @) `5 @5 S0 P! R! e
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
    + W9 I# v7 b) `% j( o3 r3 l# m2 S/ Q
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿* v8 q% o6 g. @; h( q
  31.           {2 x: ]0 P% {+ [1 M2 ?- o, f: c
  32.           pre->CapStatus = 0;" i& X2 w" e! p2 D2 `
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);! s4 k9 Y# V! M# y
  34.           //计算频率
    " r/ ?6 m. M- D# g3 O0 p- ?
  35.           pre->Frequent = 1/pre->HighTime*100000;$ W1 E/ i) W$ `4 o6 p
  36.           //计算占空比' v' z# D6 S2 \' u+ \1 ^0 J
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);# u, Z: \7 _" f+ O+ w
  38.           pre->EndFlag = 1;
    ( O- H, c4 _. m* a/ L5 ~
  39.           }4 Q/ \  _7 {, j& Q
  40.     }
    7 `: t& [. d- g6 M7 Y, Y0 n' N

  41. 5 z5 Z8 x) Q9 v& z' Z7 y, Z7 H

  42. 3 _0 k' |. P/ {$ i$ d7 B. g
  43. }
复制代码

: o8 H0 f! b( L3 q* W, r我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
$ }! T2 Z/ ^) {" q2 E: m% a  o9 W1 _6 w7 j
主要统计两个上升沿之间的时间。
: u, w' \) \7 e# X, I% j! _
& H! x& \# H( B
  1.     HAL_TIM_Base_Start_IT(&htim16);
    % r. Q/ e) ?: D
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);2 j; s4 B1 ?1 O! J( e% S
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断# `4 h6 @" h5 g, |
  4.       HAL_TIM_Base_Start_IT(&htim8);( u; w+ P/ R& [# r2 ?9 a
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);8 C9 \8 u% M3 Q2 F- t
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码

! W7 y0 y( B6 J3 S开启定时器计数以及使能中断。5 @/ P7 Z2 {8 W& t

( {% z" k' @1 O2 l' G
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)6 B/ Y/ o  [$ _5 h
  2. {' Q; y, `2 P- {
  3.   if(htim==&htim8)$ S! g6 E' x0 C( D
  4.   {
    - Z$ d- h8 d5 s  {4 ^8 z
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    . {/ N) L' Z* ^( M; ^, W
  6.   }( A5 E% v# x9 i2 G
  7. }
复制代码
1 K4 L9 r7 _. y! Q" w# p; J: ]
输入捕获到频率检测。6 m% T/ a/ C# e6 Y8 Q& e
5 W1 r6 m1 T& p6 G# V
  1.       if(pre1.EndFlag)3 w0 ?8 d' `$ e+ U
  2.       {
    " z- t& ^5 K- R& f" L
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    ( W3 X7 u2 W* V
  4.         LCD_DisplayStringLine(Line4,pr);! ~0 z6 [, S1 }; g- x4 l
  5.         pre1.EndFlag = 0;
    $ L6 C% w* q  V# p' `8 ?, y
  6.       }
复制代码

) N$ C7 H: s( W7 A; ^! X2 Y/ V" l  I如果检测结束则打印频率值。0 G2 ^$ P) c( \0 u$ t

% L& J3 ~1 F4 E& M/ f7 i$ B' }7 |
微信图片_20240529171336.png
3 A) z1 I  z" a/ g6 a+ f$ O. y
: p& l8 ?% Z1 h- ?. L% Z2 z4 s4 L8 i% \8 o% X
微信图片_20240529171330.png & {/ k% l% [1 o
8 B# q- v' Z1 Y4 H% H

; A0 e. r  P) E' [. Q我们可以看到理论最低频率为716.41HZ
9 L3 S7 ]# _4 Y) {1 K1 s9 H1 t; l8 P/ c8 t9 t) l
微信图片_20240529171326.jpg ; w5 c+ h# C, u
: J4 [" g7 [! @
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。
' I4 F- J3 b" z" g( ^0 \2 n: R2 a8 T! y

5 a! O, E! i: x/ t# D  n" V! W, n1 t/ U$ r
转载自:电路小白
1 O: e( _  l4 T如有侵权请联系删除7 ^/ Y3 |, X/ N7 G" K5 B+ }& R) Z. h
; m! B7 D+ ]. T6 R1 C6 s2 l

* ]: `2 N7 k  y6 `7 v7 X" Q7 S1 c
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版