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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。2 G; }6 E  n& w1 J

& F% L% E0 ?% Q2 H
即使用输入捕获来统计。
" {4 \. h( P, ^& ~! ?2 |) G% E- [, F/ r/ G: l
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。$ f, I5 k! D  y3 ?! }5 w0 t7 g
0 K& c, |' N8 a$ D/ G
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)
% \+ x0 [9 `( L. A+ c/ s
8 c+ J0 E2 s" y/ u# n- h. |
微信图片_20240529171352.png 0 A3 @* _: l' D) p% o$ V+ z: G

; b* X5 d. [$ [这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。
! u- o' Q( i/ l' ?. K: s
/ k# h  c+ ^0 a! d 微信图片_20240529171348.png
2 k+ x! Y5 U) A

4 U) F, h0 M4 b; o) {' _! ?这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。7 T) l; e0 Y3 i8 V$ D

9 c* d6 P0 l7 \, n4 e. `! R: i 微信图片_20240529171343.png 5 s  Z. b# v& c4 `1 L, V+ l

# h% o6 o4 l7 p2 K触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。; t' K* m$ F6 y2 f4 L4 W3 S

' C$ F, s9 f8 ]- b
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波). x+ f, D7 C" e3 H
: a! `; P1 `) ~4 J  {* c$ L
微信图片_20240529171339.png
5 V. |/ j5 Z9 p' l0 \" U, G
7 z" l! i' R# X$ r6 Z
& S" F5 B% b& Q2 m& {. k" u9 P. ]
开启定时器中断。
7 o9 Q6 y/ _3 K, v. j9 d" s; D. z
' C5 W3 s+ x5 f) O: s
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。' B; u* x0 l1 l4 H1 ^! `& Y3 J  Y
2 A. E+ L% ~5 U. X
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。2 y7 m3 |$ W4 v5 U( s
8 p+ U2 u) x* X. H* m; v
这里分频系数也不能太高,我就干脆不分频了。& X5 ~8 N7 C2 E

" _8 e- ?) [4 X0 M$ E/ `  T' ]4 @( Q
因为等会我们会清除计数器
* J5 g$ t7 M: a, F7 V" |* C. F4 b* F7 K5 I4 }4 S+ H- i: e$ K8 B
  1. struct Pre
    7 f2 W( @, C% z
  2. {
    & H8 T9 {" X' M4 v7 V; G* Q
  3.   float HighTime;//高电平时间
    7 ^4 ?$ I! W# C$ A) q) O/ T0 K% L
  4.   float LowTime;//低电平时间+ l+ Z6 v, B/ M- J0 w1 v/ z
  5.   uint8_t CapStatus;//计算是否是第二次捕获+ N8 ~) W9 y6 E! W  Q+ ~
  6.   float Frequent;//频率值
    ( I5 x) E8 N. G
  7.   float Time;
    ; ^: P  z1 k: ]$ P+ B- [& T! n
  8.   uint8_t EndFlag;//捕获结束
    5 S7 u  y3 {9 U/ o
  9.   float Duty;//占空比4 |' `5 }/ Y+ F7 E  X6 U. D
  10. };
    7 n8 m' s8 Q/ i( ~1 c5 @
  11. ' y0 W2 E$ j, O3 U" T

  12. 1 Y: \4 c6 n8 L4 T' F3 h

  13. & P- O& M: a, U" S- C: j/ v1 G
  14. 6 q7 i3 s% j3 q( g; l; C0 [
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    + {$ r" s: {4 @
  16. {) l/ }6 M4 \; H4 m5 M/ J( F* o) g
  17.     if(!pre->EndFlag)+ G4 x/ d" C* ]' |& g" i
  18.     {
    3 [2 Z' v5 h# o$ e
  19.       if(pre->CapStatus == 0)        //第一个上升沿5 B' I% z( s/ K  Y9 A/ ]( K  C
  20.          {% t: h, P4 k9 B
  21.            pre->CapStatus = 1;
    9 [/ e: M3 Y' G+ l, `  f! \$ n5 o
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发9 ]$ a2 S: x3 Y+ G
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值$ i  i8 B5 b' E4 X! e" i  Q4 S% L3 n
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置) L! m7 ]. J4 L9 h# c& j
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿4 u5 E& u5 T. h, z7 C6 v6 h- h3 ^$ Z$ n
  26.           {
    1 d) b5 ~! D% P8 o
  27.              pre->CapStatus = 2;
    , N' n0 k; J  {. [- K
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置! Q+ S- {- {5 _" @7 E
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发* w% c% B: Y/ w& T
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿- A4 J7 g; Z1 C: O6 p8 r
  31.           {
    ; p* x! G9 T' g, w, |
  32.           pre->CapStatus = 0;& x0 a+ n5 k( _0 }  u
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);; @* D0 _4 ]' T' U9 I6 j: W
  34.           //计算频率- `- f4 `3 O% {/ l, S% s" f- u9 {
  35.           pre->Frequent = 1/pre->HighTime*100000;
    , T9 t  H5 A) P$ ^% K2 g6 S
  36.           //计算占空比
    9 _: r% {4 l& {. W
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    9 g) n* i) P3 j5 Z4 K) P! c6 p
  38.           pre->EndFlag = 1;- l- t: ]5 Z" |
  39.           }, S; z; g9 i6 s; E
  40.     }8 P% L/ i1 m3 w8 s

  41. # d3 h) R) |, R+ m( Q
  42. 6 n9 X5 v* S; T- e: x* T5 z3 J9 g
  43. }
复制代码
4 g1 u, X9 q$ a, T6 B( n
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。
6 Z- O& T2 l, P4 d/ x0 I2 K6 L" d( ?) F' c- ~
主要统计两个上升沿之间的时间。
4 N9 C6 c( V! }7 n2 _
# A9 ?  B7 U3 Q6 T) A
  1.     HAL_TIM_Base_Start_IT(&htim16);3 v" e5 `' `: i, d4 \
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
    * \% j6 P4 W' W1 r0 H$ [7 K
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断, M+ D" r- C' C
  4.       HAL_TIM_Base_Start_IT(&htim8);
    $ O0 {( `& q0 `
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    9 O8 O$ c! F9 v. ]
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
* W6 c6 j$ ^5 N
开启定时器计数以及使能中断。
1 }( v/ o9 D5 q7 _9 [9 `1 {% j: @9 u8 q7 h, j! c$ D/ P& f
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    4 V; I2 d- V. X0 s4 j7 H& \. I
  2. {
    - }8 {' f, _- z6 t& i$ T5 l  Z
  3.   if(htim==&htim8)
    3 N' Y0 P) H0 _) h# s- @
  4.   {6 l) `% R3 k. ^) U: f7 C+ h0 @
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    - [0 m: p6 |; p+ V# H: |( C* Y% g
  6.   }. O5 S! I- c7 C, y
  7. }
复制代码

& v; V- B0 d, d+ d9 u输入捕获到频率检测。
* o1 G( [9 T; F( l6 s) {, ?
- p# U* j! z5 X* r% [
  1.       if(pre1.EndFlag)4 m: {$ j2 u* _, t. `! x; w
  2.       {  \* Z' U% ?1 x; k5 W: j" Z$ q" a
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);1 {2 `1 c; k% P; C! b- ^% [5 e
  4.         LCD_DisplayStringLine(Line4,pr);
    3 m( e! t# Y) y2 b
  5.         pre1.EndFlag = 0;& W2 E* H7 X; {( m
  6.       }
复制代码
+ s7 n: D$ O% _2 O. c6 O$ n
如果检测结束则打印频率值。3 t$ R6 |# v- G8 |+ Z

& O2 X' K, I) a8 w
微信图片_20240529171336.png
# ~2 `% K; J. N5 W2 v0 q, ]( Y0 L; s' ]$ g. F' g5 z

) g. v7 E1 _1 b: a! D+ g, A' u4 C 微信图片_20240529171330.png ! A- s' D# ~) q- H1 X- v

# Y- `( E9 f/ m8 @- u2 s3 Q) ~% k+ `
我们可以看到理论最低频率为716.41HZ$ X8 r% M4 R) k( v" T# m+ [

6 N  [1 w4 G9 ]# U% q 微信图片_20240529171326.jpg
. I( C9 n0 Z& Y- T; @% y2 k7 s
, ]. c  q3 H& W
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。
" B1 z$ m& N3 Y  A2 \) Z1 G2 X9 J

, T1 h; v* e' o$ s6 q
% _( Q4 H; W) G8 K" g3 ^- D1 Y转载自:电路小白9 e% b% v+ ~/ S/ H
如有侵权请联系删除& D7 p" M3 j5 e* k6 O

% Q! C5 H* B% r# A& u; }; }
: g; k$ n8 W. R" \# g! z' V
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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