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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。) X, J) J6 t. q7 r" k/ @2 K

5 H1 ~2 a* j6 D. O  D
即使用输入捕获来统计。
& S% P5 T4 B" q$ E& v5 v( M* }5 V$ ~7 b# X1 F
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。$ o$ k1 b* X. L& a% z1 g

& `$ W; i0 f7 f, K7 I& w
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)% d5 A0 J: _- m; f( _

0 v. `  m! Z% m9 q
微信图片_20240529171352.png ( p. O! \" y% d) X0 ?9 s1 q
0 a% M: u$ T0 W7 i( ?
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。9 ^$ _, v' b2 w0 ~$ g# g( ^& n

/ `. g, ~2 h- o: ?0 v/ T 微信图片_20240529171348.png
9 U8 }+ M  T/ w1 @' ^
! R6 z# b- Y3 S" N: W
这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。
9 L* x6 c) }" I4 m, A/ [2 @3 E: C/ @
微信图片_20240529171343.png , [6 m0 Y9 ^- g0 I
1 j8 [  m. y1 w+ S
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
% ]% |% b& f; m- L
* l( c2 i5 h! q3 g
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)
, o  O' H  T( |2 m5 }7 v' @8 i* D$ o
微信图片_20240529171339.png
' d7 @# [) [( k1 \7 q( k7 _' L0 Q8 {' @: H' s* G3 U3 [/ r

2 V: }9 |) @' z; q2 K" ]开启定时器中断。' Y. H' f+ l7 F  H
, K% m1 z0 x6 L  h, A$ m* q
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。
. g- k0 T6 F4 y9 U/ ^  M, B/ k4 u9 h* I0 q! u
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。
+ g( H  g+ ~" k* {7 y, _7 s9 u& ?# j+ c  j, n( R
这里分频系数也不能太高,我就干脆不分频了。
9 S8 ]& ?& T% c$ D8 P, \! q# a$ N! E- \& v) M. \* C1 i1 M! T
因为等会我们会清除计数器2 @* R5 @# K- O9 q2 q! d
+ ?8 e9 w0 j. j: _
  1. struct Pre
    0 Q: j) G. U' J4 y2 n
  2. {
    ' F9 E2 Q: {9 w
  3.   float HighTime;//高电平时间2 N0 h& J: O0 Y  p2 O
  4.   float LowTime;//低电平时间
    ( p; e( x  p2 n4 ?# j  v
  5.   uint8_t CapStatus;//计算是否是第二次捕获; ?$ Y+ v" q. k* |
  6.   float Frequent;//频率值
    * i/ a) }- t: C
  7.   float Time;$ u; d' O. e5 @1 ^: D2 k
  8.   uint8_t EndFlag;//捕获结束2 L- G% U& b* y5 A+ Y
  9.   float Duty;//占空比
    / t- N0 }+ S* \# m' F6 i, u
  10. };4 D* ]6 K* }" t# v- ?

  11. ; V8 |9 _0 p/ c- s
  12. % F  O+ M4 E7 q" p" c

  13. ! ?2 w9 W0 R/ G! _
  14. 4 j1 ]0 c% y  @. A# U9 A
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)( G) U0 P* o  ~- n
  16. {
    7 o! l" `; t1 ~
  17.     if(!pre->EndFlag); I% N7 g5 U8 H+ m' l# x1 Y; y
  18.     {
    $ d; M+ u, K0 M
  19.       if(pre->CapStatus == 0)        //第一个上升沿& p- G. R& G+ n% |( c) C+ _& B
  20.          {7 i# x" p6 y( R0 L
  21.            pre->CapStatus = 1;. a) L/ l, ^! D. h+ @
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发7 Z) p6 B0 M! J7 i3 m9 \( _- G
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
    ! h3 m# V9 Y8 \& `$ M
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置8 r% M" @% V9 z
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿
    4 ^* d5 S7 a; B6 m
  26.           {5 J$ T# S% U. u8 U5 F' |6 k/ i
  27.              pre->CapStatus = 2;
    , E+ u% t, m) w( f# Y* E: \* M& }2 J
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置& d+ ?$ f* V$ y1 i/ A, \8 p
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
    ; }  l8 h: Q& V  Y8 |2 o4 [7 @* ^3 ^
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿
    5 e/ Y" v* Q- Z( e' A) O0 P; B: D
  31.           {
    / ^. b: A$ Q8 u0 I
  32.           pre->CapStatus = 0;
    4 `. \5 `% O# \" Y  ?7 m8 k
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);9 R9 ^+ r) @( b9 b  M3 V' V
  34.           //计算频率
    : E1 G" k" f, J- j1 S' @% w
  35.           pre->Frequent = 1/pre->HighTime*100000;
    " i' x" O. D- f% W0 v
  36.           //计算占空比
    / @8 Q* o1 b! l
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    ' u0 M! p6 C+ m. ~" z: O
  38.           pre->EndFlag = 1;
    1 T$ ?# k: s  A/ x( Y5 k
  39.           }
    6 }, t$ _+ x+ B8 I
  40.     }% ^' \. a9 O3 d& |

  41. 1 P( d8 Z: E8 A' g2 `/ {2 w& B
  42. + h0 v. V" s' O5 I  h
  43. }
复制代码
7 h& w( q! x  x6 [- S
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。: D1 i- R7 l! g7 c

& d" M$ {- _2 M
主要统计两个上升沿之间的时间。
& U; `2 N0 N, y9 |" Z6 x; c$ D8 p9 C/ W( {$ V2 K) ~% N
  1.     HAL_TIM_Base_Start_IT(&htim16);
    7 k' l0 ?: d- X/ `5 }
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);( ]: B0 f) X; W& p( o. s
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断% s; j5 _* P6 w  ?8 t! u
  4.       HAL_TIM_Base_Start_IT(&htim8);9 S7 L. |9 J4 S) S
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    4 W: P* Z0 R& I; R* H
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
, s" |0 n2 a- Q4 Q
开启定时器计数以及使能中断。
6 p5 E3 l! s9 Z' \+ Q
# i' W* m7 d; B. B4 |% F
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim), Z0 @6 W  t$ K! |  X
  2. {
    & _* {+ G! W6 m# |2 {% Y1 i
  3.   if(htim==&htim8)
    , H+ Y& o4 Z( d9 ~) n+ ^8 z+ c7 V/ e' z
  4.   {
    & q: E* H8 x) q& j+ l
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    % [  g6 S8 s) d; H2 ]  N6 g' M3 c
  6.   }/ e7 e' Q$ |1 a* J6 U) I% ?
  7. }
复制代码
5 b+ b! |0 N9 Z
输入捕获到频率检测。. _" C" f+ d6 [  G" `2 y
  [) k0 S( @- B* [" J1 j
  1.       if(pre1.EndFlag)
    ; j) K$ ^7 E% R* c# Y
  2.       {
    2 Y$ C" R5 W) k2 a/ ^! A
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);' o7 W7 H/ o0 u8 a1 s/ N  _
  4.         LCD_DisplayStringLine(Line4,pr);
    9 r7 T' @; z2 }( P1 ~# [
  5.         pre1.EndFlag = 0;
    9 q  Z% z: d3 j, [: K
  6.       }
复制代码
* C  E+ P* ]) {" Z! m% K( b) d
如果检测结束则打印频率值。
5 }- m( k+ r/ d" X2 u6 Q) u  g7 A
) n- f( d9 {2 r! O2 C& O% \4 T
微信图片_20240529171336.png
2 O0 q4 ~0 Y; ?9 m
3 T  {2 a; f9 a9 J' t' t
* D' e, E% h) T9 [: K* Y! x 微信图片_20240529171330.png
6 d: E3 R4 [2 D0 e2 {# ]( p- J6 a9 |9 _
+ v$ B5 b" S1 K, ~1 ?
我们可以看到理论最低频率为716.41HZ
/ w8 H! U2 |$ `/ k
, a1 ]! E- w0 x( _ 微信图片_20240529171326.jpg
$ d) [% q& B1 e* J; `

+ }6 d3 J3 k+ G1 x$ J可以看到测量最低频率为713.17HZ和理论值的差距非常的小。
$ ^. ^1 S9 r" D1 g9 C
: I! l5 C0 W- f7 J5 @  ?& Z# }
/ ^) S' Y- R8 W# _

: K' T8 G# Q6 n/ I' g4 `4 h- i转载自:电路小白! y; u6 d+ p$ z' P6 b; K
如有侵权请联系删除. A( a1 h/ X% {) Q( o

6 r) F+ J" d) ~7 M$ p3 V8 h7 M+ r# M/ @$ J# U+ O
赞 收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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