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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
* L1 |! y* }( i& ^, Y' k( q5 V1 l6 x4 B' j$ e+ a
即使用输入捕获来统计。( Z9 h" W' X' G" `* }" Y$ F, D% x7 _! c

  L  ^* B1 B4 f, Z0 l- _2 \1 y
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。2 R/ ~! m& n" r1 X1 Z8 U
* x& t: [. z" _" A
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)
5 X" p! g& o& `, X2 [7 [' @; P% B- I* ?/ N( f
微信图片_20240529171352.png ! I# k% d# }+ g/ m

& w1 O1 E+ k; L7 ^这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。3 p2 }- D: I% s
1 l& B8 U9 B7 ?, U( l! Q
微信图片_20240529171348.png 5 @9 u9 {2 ~' k/ L/ |+ s1 _8 v
' Y" W2 Q$ h* `  n$ e8 G5 [* l( _
这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。0 |$ ^1 Y2 O) S9 b: b
+ e5 N( F% k7 b* a; i
微信图片_20240529171343.png 0 i4 M# ?$ r+ m% V2 J) F; L

& a/ i/ ]  o: o$ t6 V% T触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
! g4 l( |" [6 I/ C( |7 H: u7 U0 R1 _& o. |  q
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波). _. V$ M) Y! j7 B& ^3 r9 A* I
8 w4 `6 u" l. }; I8 P( I2 v
微信图片_20240529171339.png
6 h/ t* I& t7 o7 a
0 m/ z& d  A* z- O$ Y: b

  d0 R, t& L/ l4 f) d1 i/ k开启定时器中断。
. ^3 z- k7 X% p8 [6 V
6 m3 J2 W$ A5 \6 F# _3 B- l/ C
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。; K7 A( W0 k1 {) ]. I1 Z
) h% Q, F0 P$ F) I7 }
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。
8 s: h# p% r" N6 y# f
$ J/ Y6 I- G( z2 _( I6 e
这里分频系数也不能太高,我就干脆不分频了。- C- U' c" x% c' _; _

( ?# ]) R4 Y6 V$ R$ B3 S4 m. a
因为等会我们会清除计数器
; A  R4 I; s; e. ^
6 h8 J: o4 o2 {5 ~% k& T; I' h9 m+ f
  1. struct Pre$ p  [$ A( j0 f5 M- v( a0 v
  2. {
    * U, A  f7 V0 H: e
  3.   float HighTime;//高电平时间8 r9 U- ~" j0 l: Q! ]
  4.   float LowTime;//低电平时间' L2 g& {6 B% X$ M$ J7 T& x
  5.   uint8_t CapStatus;//计算是否是第二次捕获
    / R# {2 e  y$ h5 p6 O
  6.   float Frequent;//频率值
    / \9 W+ K5 G) _3 g
  7.   float Time;
    8 j- o7 K6 @( v
  8.   uint8_t EndFlag;//捕获结束
      B: l$ T. k. x  W3 X  I7 H9 |
  9.   float Duty;//占空比
    " o' e) z1 D4 `5 V4 e" r
  10. };
    / N& \1 t1 e5 m; H' @  V; P

  11. $ e9 u0 d. I' Q! d6 d: s4 S& g1 n: r) h
  12. % L% H* k' i; Y/ p* H" w

  13. + |# {' X4 }, h* D0 Q3 o

  14. % c* N6 y1 c2 S1 V
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)3 T% J8 i# x5 @6 D! V( C
  16. {# l) E  A( N/ z1 J6 R
  17.     if(!pre->EndFlag)
    + Q6 {6 t, x7 T3 y
  18.     {
    ( S. q; N( ?* n; T" t
  19.       if(pre->CapStatus == 0)        //第一个上升沿
    ( a# \  J% q  S- ]  H, g/ \- t
  20.          {
    ( K8 r! `4 Z9 L- x$ W0 O' J) v
  21.            pre->CapStatus = 1;* _+ u4 i! K" N: X) L& k$ n
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
    : @4 A) R9 o" c, ?9 F
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值/ s; f; _, {: S; F1 j0 e
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置; G5 K% _! g, C, e
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿
    1 Q* ]& V& w  b# h9 ~' }; z
  26.           {
    $ M) B+ m" ]8 G
  27.              pre->CapStatus = 2;
    3 ]6 a3 u- h* s. [2 C
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置
    0 j% e, g. g- @  a5 U, R
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发0 o3 _. I. x' ]; p' V2 A& \
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿
    ( @- o6 n, X3 q) w
  31.           {2 G  p) b8 U1 Y/ L) B
  32.           pre->CapStatus = 0;
    2 x: |& H7 W/ ^
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);
    $ e2 |7 C! y& i& _; w6 p3 f
  34.           //计算频率
    5 ~" K  j  ?6 Q# q
  35.           pre->Frequent = 1/pre->HighTime*100000;
    / O) e! [6 O4 Y
  36.           //计算占空比
    8 `; C. b( r. @* A7 q
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    / Q! `: Z# T) Q* N
  38.           pre->EndFlag = 1;1 f6 Z: I* _& B& K) J9 \# l1 Q9 u8 [
  39.           }
    ( q4 f5 ]$ a4 Z; V7 u2 O
  40.     }
    6 M9 I! ?: ^, v# x( K# l

  41. $ ]1 ~9 v8 c, v
  42. 0 W$ Z) Y2 Y# y! R! B& s
  43. }
复制代码
, D6 u& V+ A8 |9 d5 u8 g7 J
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
& n5 A8 E* ^4 b! I- x& o; n9 z: T. Y/ p$ w' t3 m+ I; ?9 ]  T
主要统计两个上升沿之间的时间。' h7 T9 W" o% q# d. e9 m7 H3 I

- e* p% @2 ?9 S
  1.     HAL_TIM_Base_Start_IT(&htim16);
    ; t: l7 T& y/ v) X
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
    + y& y1 ~0 w) `" ?& F2 B
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断
    9 @9 W* r: f6 m& g: S
  4.       HAL_TIM_Base_Start_IT(&htim8);3 X. K) A, u) p" a% w" T
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);: a3 x% @1 Y2 }  R, n# A- a9 [
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
; G6 p; |' ?8 j6 R- y: d& W
开启定时器计数以及使能中断。
& F: p" j0 I3 s  P8 I% U) n( G' W3 I2 z  G! d; y
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    + r) u' o# _4 |2 x% c3 h3 h
  2. {9 k0 i# x' }8 m4 z
  3.   if(htim==&htim8)- I( h: D/ a) S2 n3 I/ u
  4.   {4 W5 v  K$ E7 T) {' P
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    6 X+ P- E, `4 d0 C3 ]% o
  6.   }% i; V5 N) Q% z( T
  7. }
复制代码
/ n8 Q& M& R3 ^! k
输入捕获到频率检测。. O! ~1 i* ~1 P! O7 m9 Z1 l
4 l% L+ T7 j; ~% ]6 y3 X  e* l1 F/ E
  1.       if(pre1.EndFlag)
    4 e- c+ [7 F% s; v7 F; S9 W5 R* ~
  2.       {
    9 b" \! i: _" ^2 v
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);1 T4 A3 u: G3 \% O* d  c
  4.         LCD_DisplayStringLine(Line4,pr);
    % E, F0 Y; V9 Y6 \( m
  5.         pre1.EndFlag = 0;
    ( @$ ~4 h7 A1 t1 ], v( s) ^, s) s
  6.       }
复制代码
+ \4 u, G* Q  `, O9 K
如果检测结束则打印频率值。/ ~+ ?' b5 ]* A7 s0 a6 F! N

4 G4 D8 ?5 F5 n5 i5 R& V
微信图片_20240529171336.png ) Y% G4 M! H5 _9 Q) {' v& m

) S% Z: ^; l/ M( L5 h  S
8 l+ q1 _- _( c5 N 微信图片_20240529171330.png 7 B% g3 h* f, i" T% t% O

' f! D+ r: n6 c0 M  g
2 O. c( W8 m7 v1 Q6 P! \. h& ^( ^, \我们可以看到理论最低频率为716.41HZ
* B6 G" w6 ~) V! ]& C8 m# ~/ ~: y. O  z5 X) q6 j
微信图片_20240529171326.jpg
$ y/ W  D+ B& H4 O3 K
' x# R9 k+ u+ |/ M% N
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。- `/ b5 j- Q7 |. \9 @) F0 H' D
3 ^% V7 ]0 F2 H' o  L* x

2 F$ \+ l3 @6 l2 ?1 Z& h/ p) M5 U# N  k2 n! x4 U
转载自:电路小白
. T, o4 [4 ^5 B8 v# J如有侵权请联系删除
7 i  q) C' E$ g3 z' b* V0 D

8 q  ]& t  ?( ~3 N0 `
9 [2 i9 l9 i4 p- Q* X0 `
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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