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

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

[复制链接]
攻城狮Melo 发布时间:2024-5-29 17:14
STM32统计频率有许多种方式,有使用外部中断+定时器的方法,但是还有一种更加准确,可以计算占空比的方法。
+ ^  p* p; e9 E4 {  x
; R. q& F7 j2 c- z3 E4 K
即使用输入捕获来统计。
. ]' l/ T) }; m/ [9 Y8 D$ y1 N* a0 |7 E8 s7 P
输入捕获的基本原理是通过检测TIMx_CHx上的边沿信号(如上升沿或下降沿),在边沿信号发生跳变时,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCRx)中,从而完成一次捕获。此外,还可以配置捕获时是否触发中断或DMA等。
0 G1 h3 ]$ X. h& L* C* o# x
" T6 O1 m4 d  B5 R' n/ `
我们可以配置一个外部中断的中断回调函数,在中断回调函数中,我们可以计算两个脉冲的时间差来准确的计算脉冲的周期(频率)5 C6 B" M' E& O- N5 o3 F3 T; j/ m
% r. M! A" ^! p! L- q7 D) W2 B
微信图片_20240529171352.png ! c' j; H# g, N! T2 G

) t$ U4 m9 K: D$ e6 R4 m这里我使用蓝桥杯的竞赛平台,STM32G431原理图中有两个NE555产生方波连接至PA15和PB4。
$ e3 w  {& i  P8 b4 U. U
1 x$ y1 q; _! @& t 微信图片_20240529171348.png - c1 R: }$ A4 e  z) A

. D1 n5 }& V: i( ]* b: w3 ]这里的PB4和PA15分别对应了TIM16的CHANNLE1和TIM8的CHANNLE1。
6 {: g4 }4 _/ }" \8 v
! p, F2 b, [" p8 X 微信图片_20240529171343.png
2 E& p& I4 ?' n" H( p' W
8 I/ j: Y( K" R6 s+ O
触发方式选择上升沿触发,这边定时器分频系数选择150-1,1us计数一次,最高计数65535即计数时间65.53ms,对应的最低频率为15HZ。
: k! @: N8 T/ o7 p- @! ]* {" V& P  g8 l
最高计数频率为1us即100KHZ,滤波系数选择0(因为不是按键没有杂波)9 U! S$ r* s1 }, k1 S; w

/ v" U. ~1 o  O% x3 J9 w, U3 I
微信图片_20240529171339.png : [6 F7 D  g1 h& i9 ?
# o7 C0 `" U5 y% a

* S( A, ^+ z& W% |5 S开启定时器中断。
: G9 W2 [! k6 m7 ?& N" E: ?9 N( X& u3 `' `+ O' R' y. J' b, G
这里的中断触发有两种可能:第一是计数器溢出导致的中断触发,第二种是检测到上升下降沿导致的中断触发。  K  t; U7 O$ d6 Q# _

6 B; z8 K: O9 T, a& g
由于我们的测量频率在我们的计数频率之内,所以我们不考虑计数溢出导致的中断触发。, L+ f% O- B& [# ]0 S
* I/ m3 ]0 J6 S4 z! \
这里分频系数也不能太高,我就干脆不分频了。$ ~/ ^+ S7 e. ?' }0 X
, T) ~/ m- O& G8 Z0 H$ P
因为等会我们会清除计数器: \3 f& Q, n+ j9 [! B7 I

- J4 i9 K/ v% v9 [
  1. struct Pre
    ' U/ h1 L* Q+ i" ?  f( A/ A
  2. {
    0 ^: {  k# [0 d( E- u
  3.   float HighTime;//高电平时间
    3 I& ^6 F* H, E* Q/ m. b+ I
  4.   float LowTime;//低电平时间
    0 ]3 ?5 w- X# C" L) W! S. l5 z+ S
  5.   uint8_t CapStatus;//计算是否是第二次捕获- Y) k3 U2 {* m
  6.   float Frequent;//频率值
    & |9 \1 r2 o9 ~: z. q) w
  7.   float Time;# l1 E2 y- u# Y8 {; g! m8 @% S
  8.   uint8_t EndFlag;//捕获结束
      Q- _5 [9 P1 y" Q# [: ?- D" {( I
  9.   float Duty;//占空比: d4 l5 M' I3 _4 l" q: ?
  10. };" n/ \6 A! s0 [1 R5 |8 Q5 O

  11. ! \5 \1 }" }( g4 A) H1 P1 _% D, h
  12.   T( c, w( ?- f7 c# O6 S( u2 M' z9 n
  13. ; ?6 q8 S9 P* g* S3 p3 _

  14. - |( W* v" n. e8 V
  15. void GetFreq(struct Pre*pre,TIM_HandleTypeDef * htim,uint32_t Channel)
    7 h* Y" N, o* o; u* k: X) i' f
  16. {5 ~( `7 m( S; l
  17.     if(!pre->EndFlag)6 O: ^( [* c6 t
  18.     {
    9 B1 @4 z) T) E. ?5 {0 w
  19.       if(pre->CapStatus == 0)        //第一个上升沿
    & S$ n0 o# h! Q7 F9 ^9 m
  20.          {
    3 j6 a+ ?8 f8 U) w
  21.            pre->CapStatus = 1;* Y* K; q# A8 \5 g% Q/ i
  22.            __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel, TIM_INPUTCHANNELPOLARITY_FALLING); //设置成下降沿触发! ~# W/ O5 B! E4 j* v4 r
  23.            __HAL_TIM_SetCounter(htim, 0);    //清空定时器计数值
    + ~+ w) m3 k- k9 L' u$ R
  24.            pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //由第一个上升沿设为起始位置
    2 O/ [9 y/ V8 S2 f% a
  25.           }else if(pre->CapStatus == 1)    //第一个下降沿$ k3 d6 b1 t4 u! l
  26.           {
    & ?6 H% m. g& |6 A3 b5 L& n! f
  27.              pre->CapStatus = 2;. N8 M0 G  E2 v; s$ C
  28.              pre->LowTime = HAL_TIM_ReadCapturedValue(htim, Channel);    //低电平起始位置
    $ I% u: d; S' W5 B/ Y+ _6 @
  29.              __HAL_TIM_SET_CAPTUREPOLARITY(htim, Channel,TIM_INPUTCHANNELPOLARITY_RISING); //设置成上升沿触发
    + I2 M( h/ F6 z( H
  30.           }else if(pre->CapStatus == 2)    //第二个上升沿; k, ^2 k. t$ X' G
  31.           {* Q/ u! c. w: z: T% V
  32.           pre->CapStatus = 0;$ x7 E$ e1 z2 f; K3 m: G
  33.           pre->HighTime = HAL_TIM_ReadCapturedValue(htim, Channel);: h' ^9 p7 N0 _% E) C8 `; M
  34.           //计算频率1 B! T  o+ W! K! Z
  35.           pre->Frequent = 1/pre->HighTime*100000;
    ; o, k9 }! X% `1 o9 x0 t
  36.           //计算占空比
    0 e2 V/ o. ]0 }* a5 B& x; [1 G
  37.           pre->Duty = (float)pre->LowTime / (pre->HighTime+1);
    ! t7 S( ?; p: q6 G
  38.           pre->EndFlag = 1;2 j; |# M" v3 W5 P/ q, b' S" z, z3 m3 G( N
  39.           }
    , A' y; M* v, L; J( D: \6 B3 v8 H# p
  40.     }
    + u7 X! r* V) C8 \" d) Z4 h
  41. ' {. ]2 i% B. }; R- I

  42. 6 y  y+ c( F( G" |1 p$ l, |. h
  43. }
复制代码

5 }" c/ W# `3 l9 p我们定义一个结构体存放计数值和频率值,之后写一个函数来计算频率值。; Z0 _* F& t, N8 F1 r

- H$ z' v1 c) D
主要统计两个上升沿之间的时间。- `3 i* K$ [# l$ k/ f

# V0 r% C: D& i9 @
  1.     HAL_TIM_Base_Start_IT(&htim16);
    ; j6 X/ x2 D, ~3 H
  2.     HAL_TIM_IC_Start_IT(&htim16,TIM_CHANNEL_1);/ I- M1 c3 h! v7 j9 M0 p
  3.     __HAL_TIM_ENABLE_IT(&htim16,TIM_IT_UPDATE);    //一定要开启TIM16的更新中断
    ' N' s! T/ }, c: N3 ^! G
  4.       HAL_TIM_Base_Start_IT(&htim8);! R; |9 t0 b8 h% S. E
  5.     HAL_TIM_IC_Start_IT(&htim8,TIM_CHANNEL_1);
    ( e0 u4 s* \3 G, h9 H# S: v
  6.     __HAL_TIM_ENABLE_IT(&htim8,TIM_IT_UPDATE);    //一定要开启TIM8的更新中断
复制代码
8 n! l' ^# w7 K0 u+ j! X4 a
开启定时器计数以及使能中断。
9 g0 P* E) P; N  t: k8 ]; J  {/ C. P& ]" u8 m- A
  1. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
    7 I4 O, e5 p7 C
  2. {
    0 |$ p9 e2 r9 H# ~( _; g
  3.   if(htim==&htim8)
    9 U, M! s1 [$ J
  4.   {2 z. V: w- P* l4 K8 H
  5.     GetFreq(&pre1,htim,TIM_CHANNEL_1);
    & ?% r$ O  P; Q7 h4 x' v+ z
  6.   }! _& B) u/ t* ?, i9 c- X! D
  7. }
复制代码
8 h" U, e# l" ~* [8 Z4 s6 {
输入捕获到频率检测。
" }% A  Y9 S* c/ ?
) q9 x0 [( @( }* k, {
  1.       if(pre1.EndFlag)+ O/ I; h* b' V* V, J) f2 T
  2.       {4 S4 p0 g3 t$ r5 L" R3 e
  3.         sprintf(pr,"FreQuent:%.2f",pre1.Frequent);
    % d+ \! o4 _, X3 M6 y  {, p
  4.         LCD_DisplayStringLine(Line4,pr);' W0 o8 K1 ^( ~) K: h
  5.         pre1.EndFlag = 0;( X& Q) W1 f' ^2 g# B9 Y! t
  6.       }
复制代码

) P' |) V& A* J8 G# m4 R如果检测结束则打印频率值。
3 p2 B% y* ]- i: r3 M7 y# c  z% c8 j
3 G( B/ j( \- `: b8 h1 b
微信图片_20240529171336.png
( [7 e* t+ ^6 J, i: U( S# y; a4 r& w0 l/ B3 ~/ H

, N8 \" ]: ]% t2 I& t! O 微信图片_20240529171330.png
8 T# E" V$ h2 K# w; V) ^! o: P1 S! ^0 C4 P+ }" ~( L

# Z% U+ B6 A) G* g我们可以看到理论最低频率为716.41HZ4 _" e6 U. \! H1 o) ^' E( D& u
: r! J4 C4 f& m8 h; D0 g# y
微信图片_20240529171326.jpg 9 o8 U5 c, b5 Q5 }! s0 G8 [' {- [% n
& Q3 C" `; O: `
可以看到测量最低频率为713.17HZ和理论值的差距非常的小。/ S0 L  g9 @3 [2 Z3 {4 O" _; V

* r+ j  ^) G  S6 \) B9 F1 y

4 f5 T* q5 w# h: M! `; @( T7 S+ \
转载自:电路小白
6 N+ U  F) ?) n& _8 h如有侵权请联系删除% }& c( g- J1 ^; r

" Z6 N) K+ Q# V0 t8 P* v
! E" e  ]7 Z" G3 Y
收藏 评论0 发布时间:2024-5-29 17:14

举报

0个回答

所属标签

相似技术帖

官网相关资源

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