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

基于STM32F1外部触发脉冲计数定时器实验经验分享

[复制链接]
攻城狮Melo 发布时间:2023-5-17 17:21
STM32F1定时器实验-外部触发脉冲计数
1 n. O" [4 s  ]; W: X" ^之前我们用外部中断测量了PWM的频率,而外部触发是设置2个定时器,利用按键触发,一个定时器2用来接受外部触发信号并计数,另一个定时器6实时检测按键。9 z! w! m4 N2 Y6 R9 k; G2 ]
按照这样的思路,我们的按键读取用状态机思想去读取,使定时器6产生10ms的定时中断来实时检测按键并利用状态机设计思想处理按键信号,将PA1设置成输出引脚,设置定时器2的PA0引脚来接收信号,通过按键触发改变标志位来发送电平信号,再定义全局数存放PA0接收脉冲信号次数,最后串口配置。
/ d% S# O( O, A. D7 S0 A7 h8 U! S
. x8 ^, N; e, S说实话,状态机思想可以清晰把你的代码逻辑弄清楚,这个是我自己写按键时画的草图:" F2 \4 M& F; B) u8 a
0 x1 v) J- u: _- e3 `
1c7af8ac65064314a19f83d273578e06.jpg ' |" U. z) m% o9 s; N( I8 T8 ?

; x" E2 o8 {; @) n: H( `画的只要你自己可以看懂就行
1 E0 U6 b* N& Q! ?' N9 H/ {% P  x- [6 E. M

7 u" v- s. A. U9 S$ v9 o% D代码讲解
' i  M* P9 E" }$ x  H6 `3 ]( \2 F$ t首先我们需要按键的状态,它的状态分为检测,按下,释放,所以定义枚举类型的结构体3 M5 x, v' B; g) O! u% V9 s
  1. /* USER CODE BEGIN PTD */( M6 C0 E. s  Q4 C  w: B9 W, s
  2. typedef enum( C2 L: _2 a. k" S7 q
  3. {
    + r; W' U1 z* ?% U- H0 Z2 e
  4.         KEY_CHECK=0,
    $ ?' K2 I2 \# l5 B- R; ?1 |
  5.         KEY_CONFRIM,
    6 u/ Y, a8 a* U6 r1 A0 Z0 F
  6.         KEY_RELAESE
    % E9 z! |4 S3 Z
  7. }KEY_STATE;1 H" F8 q4 m9 E( C
  8. /* USER CODE END PTD */6 e4 m2 [3 P8 K8 V" o: J0 x
复制代码
8 g7 L; z7 t: g
状态变量的定义以及标志位,计数值& e% D5 F' S  m1 l
  1. /* USER CODE BEGIN PV */. z* d) y$ S0 l
  2. KEY_STATE  keyState=KEY_CHECK;
    ( S; n" I% u7 ]1 R& U( r
  3. int Result=0;& f& Q/ M3 g3 R9 h2 ^
  4. uint8_t keyvalue=0;
    " V' i* d* ?7 Q$ U5 S
  5. : c: Y9 P/ g* [) R9 u) c& }
  6. /* USER CODE END PV */' [- |% o9 _4 h8 v: U' g
复制代码

, l% }" |; M% V) f对于按键检测,是在TIM6里处理的,选用KEY1即PE3) `; Q" a4 M6 J2 G& e, X/ b

, S6 s* _* O2 a2 ^  ~5 H2 D1 P6 b
c310f614ea674bd7a36bab52fe7556e9.png
( [* L  j- x) N' X0 r$ k; S. w1 D8 Q+ F9 O! k) Y# l
0d925669e44a45d591c29f341f0f0b45.png 8 t: A; I2 U  |% W+ n' w8 ]
' `3 M4 q8 }1 V$ F
而之间的状态转移是通过判断电平实现的,按下时为低电平,未按下为高电平,根据我们按下的一个完整过程,我们可以通过switch语句实现我们的整个过程
5 _6 Y2 `+ U$ S! {) `+ e
  1. /* USER CODE BEGIN 4 */9 O/ V% P$ u/ h( d' A
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    2 o, z( z9 t3 x8 X7 H
  3. {
    6 Z9 A2 l8 R2 r9 \! ~: ^; @' s1 v
  4.         if(htim->Instance==TIM6)//判断是否为TIM6中断; Y) h# H# r/ i1 V
  5.         {/ C; v5 w8 \* L4 Y; A  G0 s- I
  6.                 switch(keyState)
    0 k* n  i, ^/ N* A
  7.                 {/ i- v% P6 R1 J7 J* J" w  X; n( D
  8.                         case KEY_CHECK://检测状态下
    8 K# I+ ]3 _: E1 m
  9.                         {
    8 Z6 C" Z3 P" h& s
  10.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键为低电平
    ) l/ s* U9 s6 q( b* Q! U
  11.                                 {
    . s. A4 F8 |- X2 R) W4 }- T
  12.                                         keyState=KEY_CONFRIM;//确认按下状态: v! _2 k# D$ m/ e' x0 S% e9 w
  13.                                 }
    9 q0 a' \- ~8 n0 B+ {: H, l/ j) B
  14.                                 break;
    & Y0 n" U0 Y( ^8 }& y0 \" j' V% N
  15.                         }0 W. B( x, R  u
  16.                         case KEY_CONFRIM://确认按下状态下. \6 P. M$ s- e  A7 U) e* R
  17.                         {
      C4 c9 Y- D) j- O, _
  18.         if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//再次判断       
    / t9 n8 s2 s4 K( u# \
  19.                                 {
    ' @  n  R. s( t' B# w; J$ }' z9 c
  20.               keyvalue=1;//改变标志位用于触发脉冲信号' b' {" q2 S2 J  c8 O! k- O
  21.               keyState=KEY_RELAESE;//按下后释放  p$ c& e1 I$ ^! Q  R. S" I4 i
  22.                                 }
    0 t, F- u) p( I0 G6 A/ N
  23.          else               
    0 ^# h' z/ M8 B2 T: s
  24.                                  {
    ' M: `4 T8 N$ p$ n
  25.                                             keyState=KEY_CHECK;//排除抖动干扰或者误判,回到检测$ s9 Z- L, z; _0 y
  26.                                  }; S! v, f% E5 w5 o3 v1 W  @
  27.                                  break;
    1 T* d& L1 @/ R- N( m# [
  28.                          }
    $ F* S; o9 j* \
  29.                         case KEY_RELAESE://释放状态下$ j9 e; @& H! T' W  [
  30.                         {
    ! D3 b& r0 t2 V7 @; e3 u1 F3 @# N
  31.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_SET)        //判断按键未按下
    $ H4 }6 y' s/ I$ G
  32.                                 {/ Z' z/ b- \# ^8 k) i5 B+ G  O' A
  33.                                         keyState=KEY_CHECK;//回到检测状态  ^" @4 D% ?. J
  34.                                 //        keyvalue=1;
    ! x3 ]" s8 U3 L2 C; t0 k$ `& D1 c
  35.                                 }/ y" C/ e7 J; E0 I8 |# w8 s
  36.                                 break;. x4 ]( X& Y5 _8 J
  37.                         }  q' ?8 S) o+ Q
  38.                         default: break;7 K0 m0 Q; j. a9 b! C. N& R
  39. }
    $ `) L6 K6 m- x7 i% L4 {5 ]% `. j7 M
  40.                 }
    1 x$ b) I3 m' E7 u, o+ N2 q( n2 q
  41.         }+ E& b3 D4 I: N5 p4 H3 s9 q' H2 _
  42. /* USER CODE END 4 */
    - i7 f! V  N) w* `0 c* c
复制代码
( Z: g: L  U4 T' `4 a  O% \
主函数内% n3 [/ N( l8 }( |0 h7 d
  1.   /* USER CODE BEGIN 2 */9 ?' D5 d: K, k- a& P
  2.         HAL_TIM_Base_Start(&htim2);//开启TIM2用于计数6 W+ P, l6 E( V
  3.         HAL_TIM_Base_Start_IT(&htim6);//开启TIM6用于按键检测
    3 g" H" o+ k; Z% h
  4.         printf("Timer counter founction test: \n");//串口起始提示
    " d( P: }: [6 p" Y9 p8 P1 v7 G9 `
  5.   /* USER CODE END 2 */% `6 W# C3 j7 R5 J. V6 d5 A$ k

  6. / J; _6 U& x) O
  7.   /* Infinite loop */* q$ n! D( F! [0 p5 n( a* B: a
  8.   /* USER CODE BEGIN WHILE */( X( C5 k$ j+ }4 E3 W1 u% j
  9.   while (1)
    3 x3 ^+ b# U3 s2 u& y. u5 S
  10.   {
    " P5 g' D+ c' Q% m3 @
  11.     /* USER CODE END WHILE */
    1 L) ?3 p* W+ M( X6 @" V& H2 y

  12. & W1 p" x9 x& d  M2 n
  13.     /* USER CODE BEGIN 3 */
    8 C+ K9 X6 i. K+ |: J
  14.                 if(keyvalue==1)//如果为按下状态) h2 f) @( e# d. ^4 ?
  15.                 {
    / a- o# i2 a) e  o- ^2 N7 ?
  16.                         keyvalue=0;
    / n4 {4 S; R0 }7 W8 Y
  17.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
    8 D. L5 f: N3 m' W3 p
  18.                         HAL_Delay(1);
    4 m, a5 `- l* U# X; b5 ~1 p' k
  19.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
    3 f2 z, u, l; o1 K' ]
  20.                         HAL_Delay(1);//发出周期为2ms的脉冲6 a9 M0 }  }* k7 z
  21.                         Result=__HAL_TIM_GET_COUNTER(&htim2);//读取计数值/ I! c6 _  Z  A: b  f5 E4 o: I
  22.                         printf("Counter:%d.\n",Result);
    8 J# `% Z4 ?- }7 [. U" c
  23.                 }
    3 |8 g  c9 s7 H# g$ j: }3 i
  24.   }$ S- m/ u2 R3 E
  25.   /* USER CODE END 3 */1 t; ~( i) |1 m/ A, b( x
复制代码

9 b! \! |* N6 T/ z! OCUBEMX配置
1 f/ _+ j, C7 Z6 {3 `4 B1.时钟配置外部晶振,主时钟为72MHz% I% E! w/ w7 ]
6 m/ |  K1 b" a$ O% w+ c; r5 |
979c22c7e76f4ab78bc893bb547e198b.png 8 `. f( S6 q* z- ?; ~/ x$ ]
' _6 t/ t. X+ ?. }
34c3cc70065643e0a83680e530b4fa1f.png
0 O  {$ {" M- |* S6 g7 h; z

- e' S" ^, i, d1 T2.GPIO:选择PA1输出,PE3输入, F& T2 {. Y6 S& ?
3 B6 J1 W8 {3 {: u( k0 z9 j/ _
99ee5bd1a11d457b882ae5e5351cf12c.png
% B3 |! J0 D& L8 a. l8 D4 O  U1 G
4 O) p1 M" f0 M5 F# O1 E
3.TIM:
8 p7 z) C% D) V" Q- H- c( RTIM2:Clock Source:外部触发+ |- s/ N6 U% C5 `2 C

( l- C' w( ~  m4 b, y
dff3c1e441b548fd8fce92e0c69cc35f.png
* u4 N0 u4 m: x; P- h) _
8 z7 D; S* K8 |$ H
这时PA0为你的触发引脚
0 ^4 n: i6 y+ i+ w7 w- ~( @7 n" l9 J, o0 @! E9 [9 n
c4b66361f77d4f38a0683db19bedb4ce.png
6 E, D+ v' a1 g
6 t9 w: ?# N' D+ Q. a! t0 A) P8 C
TIM6:激活并生成10ms中断& B8 L  O7 H. l. m, s! @* S9 u

% T9 R7 V" L) B& s  m4 t
6eeb551aeaaf4abda7027fe83d121b43.png 9 O; m: d. J+ E. D3 R" A% x0 s

: X% i5 ]. ^! r5 w5 X4.usart设置
; Z# |0 C$ N3 Y9 E
- _. @$ }  d8 m( E' U/ h
a6749464d8264738a2744efc34c42a99.png
( N& y3 {- b& M: P/ C: z7 v# O2 [3 y% M
5.Project的设置,
, x; K+ X* i& m/ L
- }* l1 e  w2 T
e25a54d171e6456e9606191ea4a2796e.png 7 I/ L: [1 W0 d# I' t+ e
, `$ d: ~) }, \& t7 ?) R; \6 d
还有一个之前没注意,就是在Code Generator一栏中第一个方框里选择第二个:Copy only the necessary library files,要不一个工程就是百八十MB,占内存。" O. S# k! [3 |% q; @& O% T
; d4 f: ]  @5 s) I3 ]
a29154c1ca2a4f3587b8d571a6a4f741.png
$ w) j# J3 R  a4 e; X/ y3 C2 W3 n( H* h8 b- N* {6 F
最后生成代码1 ^5 S% W" f5 j
————————————————
" i. N, b1 t9 m, ?: j2 K1 {9 S版权声明:南山笑
8 C3 `4 Q! S/ V如有侵权请联系删除
) p( x7 Z6 ~- D+ D' _: Q
# f+ W" t! W# {
: \( ]  k8 O$ D# t9 e( ?8 y
赞 收藏 评论0 发布时间:2023-5-17 17:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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