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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。) C/ B/ t7 `- H3 N

) m* F* O% R* w1 b# W& g* ]
即使用输入捕获来统计。
" N5 @1 ]8 y' U' x# x2 |8 e: E$ s# A
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。
2 C/ `% ?0 N# ]: N* W+ A; P/ g; T$ b% U! J
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)
! R5 I6 m* O/ \3 a7 ^, |6 x1 S: Z
) g. W1 r' {9 e4 n7 p! [5 x
微信图片_20240529171352.png
  q# O) J% ~/ n/ I. P1 g1 _# i* ?1 b. R* k9 F, B$ f
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。
% V3 p+ {+ U& l+ l2 p3 R3 [% N$ l! W% x: \
微信图片_20240529171348.png 9 l3 B6 @1 H( m+ V, \
" M3 j' O! O" N8 m- @6 }
这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。- b  A& L1 l3 {6 r" q2 p

0 {+ u7 E; M/ E$ Q# k 微信图片_20240529171343.png 2 ^+ g4 t( _* s, M; l

. }, C3 r8 z& ^# Z$ J% l* a- z4 j  ?触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。2 V2 w$ a6 W' {5 D: r0 n

" i) J% `+ L. B' }& \
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)3 n+ R* O) q/ _/ z2 D& D9 K
6 y( L$ {4 s. F! j- X) a
微信图片_20240529171339.png $ n9 @7 v. w8 l
# t+ s0 ^# Y1 d: r

3 J- I4 @* l3 c7 @开启定时器中断。
$ A5 R) w5 ]  Y: I6 F& h  {( \& R* v  W) T  u
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。
- p% I9 f  ?, |5 o3 m0 M1 O9 ?* @3 c0 y: I6 U
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。
5 |3 C9 t1 N8 _1 E, X5 M# R1 H$ z! F+ ?$ v) r! _, z
这里分频系数也不能太高,我就干脆不分频了。
% I' s' d+ j! v# @4 a
# h* Z; c; R1 Q# g
因为等会我们会清除计数器- }$ r+ k, g: E* R1 [$ x

0 k7 ^' H& z1 }. W! {2 g
  1. struct Pre
    ) G2 u8 r; S0 F9 d
  2. {
    + k, [0 G5 Q1 ~, A' f% ^7 M  q$ [
  3.   float HighTime;//高电平时间7 E' k+ L+ d5 o8 f/ h
  4.   float LowTime;//低电平时间2 c1 d/ I# c/ t7 a7 H
  5.   uint8_t CapStatus;//计算是否是第二次捕获- W( y& r+ t9 B6 B
  6.   float Frequent;//频率值6 Z8 Z& p7 ]+ n6 o
  7.   float Time;
    / Y7 J. D% Q' A% J% ?) |" N7 z
  8.   uint8_t EndFlag;//捕获结束: p; e4 v; r0 f1 _( H( A6 j- \
  9.   float Duty;//占空比
    ' E9 b9 |2 d2 E) B* y
  10. };0 O( R* e+ }, F  N$ f

  11. ( X9 v/ J% G+ O3 w

  12.   W( m) z) J! t) E
  13. 2 U/ F" f, f7 l$ g
  14. ( A  `7 [* g1 }; `3 A+ L
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    8 J- f7 B- {" |7 H* J
  16. {. l$ |8 X4 C1 |4 n7 y
  17.     if(!pre->EndFlag)
    + k  @  w8 n% h) X
  18.     {/ a' k0 }7 m6 h( N& {8 G) y
  19.       if(pre->CapStatus == 0)        //第一个上升沿
    4 m7 Y& H- o* X. R: ^0 {
  20.          {
    ; g* Z! r4 N  ~
  21.            pre->CapStatus = 1;
    ' b8 L6 o1 d8 X" l8 W/ A
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
    7 _$ k$ x2 S% z
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
      T% g, Y+ n1 N" c, j6 ~9 R. b: D: g
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
    . V1 ~7 S% P0 \( I  A9 K
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿
    2 Y/ i2 i- O) q5 v
  26.           {3 h& U( p3 Z/ p- y4 B$ j1 P8 T% x
  27.              pre->CapStatus = 2;, x2 `% J. X# P) h4 O
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置, \1 o. q, J# {2 r/ ?
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
    ; S! R- V+ n: ~; P  l$ Q7 A2 x
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿; E" Z6 Y. t! F" L3 O- x
  31.           {
    6 g% S7 T; [/ P2 [
  32.           pre->CapStatus = 0;8 ~+ e  u) _6 R4 u& n5 h3 `4 d; L8 A
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);, d8 H8 h6 x3 c8 v; {
  34.           //计算频率
    * h# s6 D+ @3 L& N, I* z. i5 W5 P
  35.           pre->Frequent = 1/pre->HighTime*100000;4 \/ {2 {1 T. f# |# M) \
  36.           //计算占空比! J7 @& f- ~7 M) Y
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    : A4 S" d* G4 {. S6 i
  38.           pre->EndFlag = 1;
    9 e/ |+ j8 Q4 y' x: \  s, Q& r( V
  39.           }; G  G/ ?$ A" K& w; j2 s! p
  40.     }' c+ @, C" B0 D: W

  41. - _2 p( ]4 J" ^: I
  42. * Z! R( w8 G* s# M
  43. }
复制代码

5 }+ O5 q! F5 p6 g7 y6 P我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。! }4 K4 C2 W5 ^/ l3 L* |

& ]" O( }1 U+ K+ c" W
主要统计两个上升沿之间的时间。. u7 d: @4 @3 e8 U
' u3 X4 R! l, |& e
  1.     HAL_TIM_Base_Start_IT(&htim16);
    * U" `$ X" F& b6 f" ~& A# A
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);; j% k- {$ B! ~/ j
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断* `& K, [: M5 P2 z. G- S: e6 a8 _
  4.       HAL_TIM_Base_Start_IT(&htim8);0 Y5 P; j7 n9 g+ K
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    / |" z7 @4 r8 V7 V* e
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码

( Z+ a( C9 `- j( Z6 f) g开启定时器计数以及使能中断。
4 \6 k4 r6 n/ \
" t& R. V6 B; `+ Q6 Y
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    6 {  c+ f# Q, [/ _
  2. {: |9 L2 p  r7 y
  3.   if(htim==&htim8)
    1 B/ F. E7 H- o# {
  4.   {6 c% S: o3 ~) |$ v0 B; i9 |7 D, u
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    5 x7 P1 e5 t: f% Z# D/ b/ y
  6.   }
    4 g* c# j4 d8 P/ I
  7. }
复制代码

0 G0 k: o4 H! J  {输入捕获到频率检测。
: k# y! r, _( C: M, x* a/ P9 R( O! m
  1.       if(pre1.EndFlag)
    + y: x  P. v; P) b* {& `+ k# C6 N
  2.       {9 ^2 |$ u7 n8 T! K. E3 T- ]
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    ( `/ {- ?7 U- p3 [
  4.         LCD_DisplayStringLine(Line4,pr);
    3 v6 Q9 O2 I" ]7 j  q  U9 e! F
  5.         pre1.EndFlag = 0;, w, n5 {& w3 H# r  Y, N
  6.       }
复制代码

4 W- _. o1 r1 F, [1 f如果检测结束则打印频率值。) P0 @. f$ f/ [- p- Q7 E' [* i

  N: K; v5 L$ Q) g$ f$ M
微信图片_20240529171336.png
2 g2 v/ c; l* {7 h5 F
6 J; l; h; f% F3 R7 R( j8 m5 p* X' `1 N  v0 q  O
微信图片_20240529171330.png
- s% q; u; h/ N* b: ^) R+ I7 p$ U% y6 m2 }! r8 q
/ o3 t( _. a9 b+ r
我们可以看到理论最低频率为716.41HZ9 c5 }5 y  U; y' X+ e* o/ m& G4 G

3 ^, b& j0 a& k- s4 z 微信图片_20240529171326.jpg
( x% U" I  O5 g8 T1 j
/ |7 R" R( Q4 K: f+ Y3 k/ F
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。" {* X5 Y. Y) a3 N" l  C+ _

3 ]9 P$ s+ y; }. j) g
, N* [/ t+ b" u" h8 V$ F1 G! d

  Y9 o' s% F' U$ M) X转载自:电路小白) @8 r1 t: w5 M
如有侵权请联系删除
/ T# U/ W, f) A7 P: d# K

5 y/ z' a0 {# g! Y! ]& K6 f4 a1 x) b% g0 o
赞 收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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