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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。7 E. g% G6 i) D. V8 T; ]9 H
; \3 U" k  @+ O! k
即使用输入捕获来统计。
3 x' w' F" I$ s- Y; Q3 F) J5 Q
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。. G) ]/ ^4 d. o( y0 l
. S6 p1 _0 K" G: A& q' G
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)
4 d' G* `# c7 `$ L7 e" p% ~  |- A: V# X  z. O% `
微信图片_20240529171352.png
9 r  m( M8 B/ V' ?4 b9 b! W2 R; I) {4 P& I# G5 z7 |
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。
, A+ I/ c! {, i% L- I" r5 {1 m, W& o, [/ }/ \
微信图片_20240529171348.png
2 }0 O' f& U( x
. J' H# |) v- x! [! n/ _/ J, r
这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。
. K9 s) G1 G# i6 B! e* ~2 D9 R  v; v' T
微信图片_20240529171343.png 7 N2 K" P! j" x- t' b  R' b- S* E
& r9 E, ]( u9 |3 ^% O8 t
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
# }* X! M9 a0 f7 p, T9 S6 C! E
4 u8 }' c1 Q1 `
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)
( ~8 d' X( E1 s: A. E, g7 T; z/ S; i3 o0 b
微信图片_20240529171339.png 9 W( s8 H& @# z7 C; v% V8 J* q

. ^7 I1 f5 t8 T  `8 d: ~
! g4 P3 ]6 U) K% a6 V" }
开启定时器中断。
$ a7 L& A. ~2 ^8 e' z
8 F% k! M( e1 m) Y* Z
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。' @  E6 b: }2 m* X; [

2 e% \8 `( r) Q
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。% U0 L  p6 _" e: H/ }

) w0 }: `0 j2 K/ c! O& v% p
这里分频系数也不能太高,我就干脆不分频了。( c' J  f1 Y. w( o8 C; i8 @

0 Q- L! A, G3 S) l5 C7 V0 I
因为等会我们会清除计数器
  V  `, b$ p9 _0 q5 {( ?3 J
. T* `" E" x4 _3 M
  1. struct Pre
    ! w" d- c. A& v' \% m- U' e
  2. {2 B- @5 ^9 e$ y1 q
  3.   float HighTime;//高电平时间
    9 G( I/ e5 \& L# G2 x0 H0 c
  4.   float LowTime;//低电平时间
    7 N. A6 j& A$ }) y
  5.   uint8_t CapStatus;//计算是否是第二次捕获
    / a& o( e0 i. n# L8 z8 P$ Z( T
  6.   float Frequent;//频率值
    % s" j( S3 h: S2 e
  7.   float Time;2 P0 U! r: ?0 N, f5 o% n, |
  8.   uint8_t EndFlag;//捕获结束9 I% Q4 T$ O6 |% b2 Y; F
  9.   float Duty;//占空比1 h9 q( V, u* V1 T# l, ~- u# Q
  10. };
    7 X; W& m- ]; q8 z& b
  11. 5 Q' ^3 G- x6 b# [9 m8 E" @

  12. . u3 n. w3 N6 `+ G) b) s" ?9 t4 N5 H

  13. ! i  w& i' w2 l% y
  14. , ]$ ]( @' I  b1 j, D' T
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    5 M0 b8 z/ w5 H; V
  16. {
    1 N: x9 ]  x, ~0 u
  17.     if(!pre->EndFlag)
    8 r& A* [2 B( `; _2 y# q7 ~
  18.     {
    8 o  F* e) G. O+ w+ Z+ l3 m
  19.       if(pre->CapStatus == 0)        //第一个上升沿
    ( t- a* G2 D. ?2 b
  20.          {) [6 l; x* r% O
  21.            pre->CapStatus = 1;% R2 L" Y, P' s6 w" h+ k6 o1 [
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发8 y0 @7 y+ H( g$ g
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值& S0 D0 I. y1 j0 d2 [$ X  u0 n+ t/ Z
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置/ @$ Q. ~: j4 I
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿
    $ R  o- S/ L( b% C' Q8 v! ^0 C
  26.           {2 }5 j$ M  K) i# P7 l, K4 E
  27.              pre->CapStatus = 2;. t4 }, s  E& L* Q& o9 B1 @
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置
    8 z/ j1 O, p; z& ~+ v% B6 |' [1 o
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发" _: r3 G" |  I! w! d- v  K! T7 }( U
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿' f. u+ i3 s0 t; N, ]% O$ r
  31.           {6 l$ m% Y# S9 J) X# h& h& u1 \$ t
  32.           pre->CapStatus = 0;
    8 D4 t% z3 P( O8 y0 Z  J
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);
    ; a" c) d; H4 f; ]7 ]* E6 F4 o
  34.           //计算频率
    0 o' Z7 L+ @0 Q( x, t" {! `, p. G
  35.           pre->Frequent = 1/pre->HighTime*100000;
    + b, j6 X1 Y8 G
  36.           //计算占空比
    % i+ J% t( F% l
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);6 B3 X. u) u* ^3 \$ u
  38.           pre->EndFlag = 1;- |! W- Q: m& k# P/ z
  39.           }
    9 S0 l9 J1 [5 c/ e
  40.     }
      ]& K2 z7 S. O8 v; e
  41. . O( c% y8 m4 l% c
  42. & O3 W7 H: B6 m* g, p9 a: ^
  43. }
复制代码
- b  U8 c. K0 \0 n
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
1 h, `" r! Q; T% D9 V
  G! \# a5 [9 {4 y$ J& i
主要统计两个上升沿之间的时间。$ k  B1 B) v8 j" e2 T

6 [- b4 h; e2 |9 k3 W8 U
  1.     HAL_TIM_Base_Start_IT(&htim16);; R, P0 L8 g! R6 \& I
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
    0 L1 M: Y3 k5 v) z) k
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断; p9 h' @. m4 H0 C% @/ W* |: F# D$ l
  4.       HAL_TIM_Base_Start_IT(&htim8);
    3 G! W& k3 y3 |4 D. ^4 W) i$ R
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);: b4 \( V" O1 v+ Z! A
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码

! X( o+ G7 R# a. W; ]开启定时器计数以及使能中断。( x$ M  N# k. k) }" i8 `

/ h# f; t# a5 m- ?1 k  Z' X
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    ! {. z6 _$ [5 _1 l0 ]: |+ m6 P) A
  2. {" L1 d9 U/ j/ _1 }6 c' ?
  3.   if(htim==&htim8)" l9 a8 _; A/ Q( Q7 h: q4 k, F
  4.   {: K7 v2 [3 d, o6 w5 E$ R$ w* \
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);/ }+ L& {; \4 ]. c
  6.   }
    1 a/ d: |( \* w9 ]' f
  7. }
复制代码

, o5 g1 \. K: {输入捕获到频率检测。
) A5 B' F: i7 d( v
. T) G- [* O; z4 `! J" I
  1.       if(pre1.EndFlag)7 q( x3 W0 b8 |
  2.       {4 O$ _2 T5 ~) q  D8 z% A( u
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    / X1 o5 U: t5 V; y0 X1 q
  4.         LCD_DisplayStringLine(Line4,pr);( J1 w% R, D8 V" M* h% [
  5.         pre1.EndFlag = 0;
    ) T# Y: O0 o! |" V6 b- x( B
  6.       }
复制代码

8 q# t8 ?' w. A! _如果检测结束则打印频率值。: r8 C4 t$ r( p& y& C3 E
4 M; j' J0 f/ _& ^
微信图片_20240529171336.png 8 K  A  }0 N7 {2 K6 ?4 o1 ^
0 V" G6 G  ^% d

( g4 X- b, y% Y7 B8 X2 f 微信图片_20240529171330.png
& z& z. W2 D1 }( ~. j: U- E
" W* }2 Y) J+ x% u. u% I! C9 ]; ~5 W. T8 m5 P- u! C
我们可以看到理论最低频率为716.41HZ
* s: _* M1 }4 V- D/ v* m4 f! I. ^: b! }) e9 \
微信图片_20240529171326.jpg
( d& D( w: l' s

: z- ^: v- F3 R: F- I( O可以看到测量最低频率为713.17HZ和理论值的差距非常的小。; \: f4 d: j: \; s( ?/ [( z' s1 Z5 Q1 U
& r7 ^9 F0 \6 C2 g' w. k' {) k

& F- v, D" S& |; A0 W: N. o7 M2 y& }" Q* f& Z$ O0 a
转载自:电路小白
# W5 v/ N' \0 f2 z如有侵权请联系删除: i0 ]" y* U  ~; p) `
# a' C' a- o- K2 S- v& k* q

9 F: i; Q' O; k
赞 收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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