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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
5 ]% Q7 S' a( f, ]+ T4 P$ z7 J' U: H" V5 z
即使用输入捕获来统计。. {& H' w; Q1 \0 Z+ S+ D# E
4 i0 B5 r! c: q; G7 ?  h7 p
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。! ?0 }  }9 I& X$ E. m, y
+ [$ D* q  K8 l+ B7 P
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)
* O; b; w4 X! O, y: L2 ^3 w  R7 \+ H
微信图片_20240529171352.png
, F- M8 ^* u: F! f9 N9 [5 w  |9 P9 D: |  Y# M. Y
这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。: H" M9 v9 O6 D( p

: X' t( j0 M8 ~; v! {# O$ J' m 微信图片_20240529171348.png
( u+ P7 z2 ?& H

0 g& u8 y1 \, r9 L这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。
1 {5 w! }6 Q$ _5 j# ~% M- `: m& |$ W% B% U  ^7 P: P/ E
微信图片_20240529171343.png & L4 [0 G1 B& F) F  d+ S, q& r3 k
' `0 i- t0 i; Y5 K* s
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。% V3 f; L3 ^8 ]$ `$ B
5 q$ d4 W: J) g) {1 H2 ?
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)4 d+ `) I4 L9 w3 W& z: n
7 E( a5 c+ i9 C9 r
微信图片_20240529171339.png
5 x3 ^! k0 t/ |' ^
* [5 U5 f' m) C/ u* s6 f( T& k
1 o% G9 M8 x# j/ q3 z- p2 b
开启定时器中断。
, ^# o' ?5 h0 Q0 n* ^  h2 j! e' l9 W! a
* {8 q4 A1 t- e) p& ~1 |
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。
3 r, @3 y8 u& ?& c  V
+ u$ _" z  s- r$ S+ N/ s
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。. s( J, }9 j! ?) Q& ~& M8 N$ Z
9 h! N* a2 ~) y% Z' b" g3 ^' _) d
这里分频系数也不能太高,我就干脆不分频了。
% _" i" f+ q, e9 g' |6 O/ m  E% {! @
因为等会我们会清除计数器
: o" v; `$ L0 Y7 ~
# L8 B) O9 j/ I) P9 g# }. X- C
  1. struct Pre
    : y' h+ o2 f! s3 f0 U) X- h9 [; {
  2. {4 R' S9 }( m; K, G3 ]- W- i
  3.   float HighTime;//高电平时间0 h3 {6 b6 R' L
  4.   float LowTime;//低电平时间9 F1 r2 v$ C5 _! F( h9 B
  5.   uint8_t CapStatus;//计算是否是第二次捕获
    & G" A8 g5 P* {  X
  6.   float Frequent;//频率值
    7 j- I1 F4 D' h" A- i* g4 l
  7.   float Time;1 z5 ~. R7 Z7 W" Z0 J3 Q" n
  8.   uint8_t EndFlag;//捕获结束
    * U/ {2 j. z# q5 S' S/ n" q9 j
  9.   float Duty;//占空比9 R! o- X$ _: ^1 v7 ~" ]
  10. };
    7 I7 M- B. c+ w- w; v3 d6 K# ?

  11. + U9 y. ^8 t" u6 z8 Q& O

  12. # K  D$ a' J( v* ~3 K2 ^
  13. # a; X! n# ^" g5 ^7 Z6 ?
  14. , Q  l: S+ i% a
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    / z: N1 |% \' J. G, s; k
  16. {% A* E' C. q  W
  17.     if(!pre->EndFlag)5 F) o/ `8 J3 g
  18.     {& |/ N# ^! M6 o- h- r0 w2 L0 C
  19.       if(pre->CapStatus == 0)        //第一个上升沿& M8 ~" S" d! Q% }% \7 }- G
  20.          {# z/ @) q6 \6 j. q+ l$ D! {
  21.            pre->CapStatus = 1;: c! {* Z1 B6 Y, V. b2 P
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发
    - p5 F" k& j0 H% S
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
    % W. u" Z6 j* f
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
    ; ^1 Q" {. Q- k# B3 G
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿$ D, `, Z& R5 _: W' A
  26.           {
    6 J! d: w& g( D" V* O4 g
  27.              pre->CapStatus = 2;
    : w) V1 }+ r3 \( z4 n; E
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置- U# f- q7 y4 X* W- p# i) z$ R- z
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发( J) \4 b7 O+ f' T" @: P" Q- [
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿
    0 ^2 N+ i+ M, b
  31.           {6 {5 X5 R# T0 q& k) c
  32.           pre->CapStatus = 0;
    6 o. V6 V# ?3 l% R: K( ^
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);
    / j8 E! j9 H' Z6 P
  34.           //计算频率  A$ k2 P8 {2 |( u& k  Y3 R
  35.           pre->Frequent = 1/pre->HighTime*100000;3 j, G9 a8 J2 Q" Q3 [
  36.           //计算占空比
      ^! e, z6 Q7 R: D* f
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    ( ~) e7 ~  l1 j6 u1 X$ ?/ P
  38.           pre->EndFlag = 1;9 P3 W# {7 h& `
  39.           }
    ( F2 J( b. D4 y6 g  I
  40.     }& d0 V, c  V4 y; q6 p- e

  41. 5 a4 s$ `/ ?: E, _; ]" ]" u: i! }

  42.   W+ v% F; ^) g: R
  43. }
复制代码
3 Q/ @4 c- l/ b$ \& p4 {( n, C; `
我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。" @; i  ?9 l+ ]7 I. t

! t8 \0 }! t+ M
主要统计两个上升沿之间的时间。/ Y2 I( f# B7 ~
& l3 V  l( L8 d5 M2 [$ b
  1.     HAL_TIM_Base_Start_IT(&htim16);7 e3 g& p( O- \
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);
      Y1 W6 y& O- Z. z! N# k6 K
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断
    * u  o4 ]) e3 P$ R# u
  4.       HAL_TIM_Base_Start_IT(&htim8);' Z& p5 M0 w* J3 F  r) S" J8 D
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    9 Y2 ?' E5 v  w- p/ O2 ~! k- c
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
+ h+ w! J4 j7 Y" r
开启定时器计数以及使能中断。
' d/ P. }2 J$ C2 o
6 v, W2 r& W. I" _* _% `
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    * D* \# A& u$ q4 U) k
  2. {: R5 t3 Z7 K& X# s* U8 B; b3 C
  3.   if(htim==&htim8)  B& J& i0 S4 Q8 z0 N9 W& `5 b
  4.   {$ z7 f/ t  D2 F
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);4 ?2 X" h; p1 X4 f0 q1 F  Y& \& Q
  6.   }
    9 Z/ }8 E) C& |% Q
  7. }
复制代码
9 z# [) Y* r: u+ B" `, q8 z/ C( [
输入捕获到频率检测。* ~. ^7 B( U5 D( j- A

5 ]3 W* i. `5 Q# g
  1.       if(pre1.EndFlag)! k5 W) k% ?7 R8 P7 t
  2.       {3 s& _/ @& I% P: @0 p* }
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);, ?2 ~( }; v% I8 k
  4.         LCD_DisplayStringLine(Line4,pr);
    ( \3 K# Q. T5 W/ E! |
  5.         pre1.EndFlag = 0;0 t, q. T% W. n5 V% M  U/ f
  6.       }
复制代码
/ D3 M6 P' q2 z
如果检测结束则打印频率值。
+ \. q5 s; A3 \  [4 p3 R
' }# ]9 G, r3 @# A$ G3 {
微信图片_20240529171336.png
3 |1 P6 W) P+ G
; W" G/ {2 ?. c* P# s( A/ N; x' d8 q: N; k! D1 P) O! P
微信图片_20240529171330.png
. z2 d6 @+ n' _
. r) f" B9 P" v' P0 \5 K5 q* H
' `! h# Y: y+ F$ l我们可以看到理论最低频率为716.41HZ
0 T; D4 S% \, j' G+ ]" E! {, I+ P
* g' D: n5 |; y2 v 微信图片_20240529171326.jpg
! g/ J$ ?4 |3 ^1 R( v1 {5 Z: E

% |, H- J, E9 g) x( o' Y可以看到测量最低频率为713.17HZ和理论值的差距非常的小。
+ G5 B* s( V! P
- ?# ?, W2 v: A: n6 i1 G

3 j& s/ `& Z  \" H2 V( J+ o2 C, n" _+ p5 c/ a, M/ q8 _) H
转载自:电路小白( v$ h' y5 k( L8 _+ ]
如有侵权请联系删除
% I( M$ S& o) @' Z' Y
% d( W) J" n1 m+ A2 f) d1 p7 `4 a1 S

, ~! X, l, z" n
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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