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

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

[复制链接]
攻城狮Melo 发布时间:2023-5-17 17:21
STM32F1定时器实验-外部触发脉冲计数
& p6 H; k& x- ]' U之前我们用外部中断测量了PWM的频率,而外部触发是设置2个定时器,利用按键触发,一个定时器2用来接受外部触发信号并计数,另一个定时器6实时检测按键。
( e- W5 ]  N* ~% c按照这样的思路,我们的按键读取用状态机思想去读取,使定时器6产生10ms的定时中断来实时检测按键并利用状态机设计思想处理按键信号,将PA1设置成输出引脚,设置定时器2的PA0引脚来接收信号,通过按键触发改变标志位来发送电平信号,再定义全局数存放PA0接收脉冲信号次数,最后串口配置。
4 v2 e6 b$ ]+ X. I! L& x
  _& X" \) Z# @3 a说实话,状态机思想可以清晰把你的代码逻辑弄清楚,这个是我自己写按键时画的草图:, s; a6 K2 w6 _1 b" P
+ V8 @% p. ]/ }/ z" N/ d
1c7af8ac65064314a19f83d273578e06.jpg
& y6 U+ Q# L* A7 H% E& r, n0 }
4 w# d0 U9 E0 v" Q9 o6 ]
画的只要你自己可以看懂就行. p" E. k) f+ }( z2 a

1 L) Z8 L+ Y& ~; t/ g& p+ _
9 Q7 }5 ?( U0 D) P& g
代码讲解
$ @. ~* X$ D3 ]$ o6 s+ p# Q, W首先我们需要按键的状态,它的状态分为检测,按下,释放,所以定义枚举类型的结构体  w4 E4 W- J! u" t
  1. /* USER CODE BEGIN PTD */; m, P! B) Q7 r' P2 H& y* x
  2. typedef enum
    * f+ k( ?  q& E5 k
  3. {
    & M# @: [4 T8 X; [- l
  4.         KEY_CHECK=0,
    : l9 v2 `' ^" j8 O
  5.         KEY_CONFRIM,
    - Y, m$ t& X9 k
  6.         KEY_RELAESE
    ! J$ e1 R2 O# Z  D
  7. }KEY_STATE;' a9 p1 F* d# O' b) w$ h
  8. /* USER CODE END PTD */% X) `6 n' j9 o9 ~8 }0 b  G  k' a
复制代码

0 q/ H3 s! l6 |) u7 C. B, p状态变量的定义以及标志位,计数值
$ D1 {# p" b) W5 U! z/ c
  1. /* USER CODE BEGIN PV */& ?3 c4 A; W/ T, ~: w. F
  2. KEY_STATE  keyState=KEY_CHECK;. R' t+ P& M  B
  3. int Result=0;
    0 t. o& _3 m1 B, L' E
  4. uint8_t keyvalue=0;- [6 S- Q8 f5 e( X6 n& q
  5. 5 Y7 c) B3 E3 A
  6. /* USER CODE END PV */
    9 f1 b) u" |7 e
复制代码
& n) Q5 q0 |! V4 H
对于按键检测,是在TIM6里处理的,选用KEY1即PE38 s; n9 R6 _9 S/ I9 ^+ A

; m9 o# p2 }' ~( w" ~4 t
c310f614ea674bd7a36bab52fe7556e9.png
7 W: D& G- c4 v$ v
  L3 E7 {; s$ K% N+ c; J' y- ?
0d925669e44a45d591c29f341f0f0b45.png
7 U  G+ s# Y0 J5 |3 Q
/ {2 c/ b0 Z. W( {4 Y
而之间的状态转移是通过判断电平实现的,按下时为低电平,未按下为高电平,根据我们按下的一个完整过程,我们可以通过switch语句实现我们的整个过程
* U7 v$ ~. _0 G) Z/ W
  1. /* USER CODE BEGIN 4 */4 ?5 O9 l/ h- R3 x( |& h, h
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    8 ^+ h( O. B& m) t% v$ I0 A
  3. {
    $ V5 f, M+ t) {: ]' [
  4.         if(htim->Instance==TIM6)//判断是否为TIM6中断
    4 ?4 _/ n9 \! K. P9 [% p
  5.         {
    % m) {9 o0 A  W2 _! }
  6.                 switch(keyState)
    ' f8 W- d/ A3 n' H! F
  7.                 {( d9 k1 j" e2 r0 a' G; j
  8.                         case KEY_CHECK://检测状态下
    : d* `/ x! ^, T2 X3 U
  9.                         {( @' D4 t; k; B: O1 e
  10.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键为低电平
    ; C# \) P2 Q! z7 V! M8 ?+ H
  11.                                 {! Q2 X& [7 U/ A% k$ F4 N
  12.                                         keyState=KEY_CONFRIM;//确认按下状态* s& e2 i" ]; z
  13.                                 }
    " [! ~9 T4 \8 k3 R
  14.                                 break;0 G+ ^. W2 p9 C7 K& {
  15.                         }5 O: B  {4 V& e( Y: o
  16.                         case KEY_CONFRIM://确认按下状态下& j$ y" g2 |/ l" J0 j; f! q
  17.                         {
    6 C% B5 O8 R; Y8 d% w8 M2 p
  18.         if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//再次判断        / R# q. d! Z; x8 j( A
  19.                                 {# a8 z- w# ?% z1 d
  20.               keyvalue=1;//改变标志位用于触发脉冲信号% y4 a& P8 f  ~4 G
  21.               keyState=KEY_RELAESE;//按下后释放
    1 l& M5 R3 L2 T1 M; e# n
  22.                                 }. G  ?# i" g- E; e* t2 `6 S4 }: r) u
  23.          else               
    ( T3 G( Q7 d: W
  24.                                  {
    9 P* U5 d6 B% k& A1 d1 f+ X+ [9 r
  25.                                             keyState=KEY_CHECK;//排除抖动干扰或者误判,回到检测. `3 H% B: o/ y
  26.                                  }
    / I+ a- v/ g! P7 g& P. u& w
  27.                                  break;" @% \6 S  Y  b5 g; X
  28.                          }
    4 {) R+ w* m: T' i( `$ ^, O
  29.                         case KEY_RELAESE://释放状态下
    0 T1 E' ^% ~9 Y/ q
  30.                         {
    9 \, g6 ~" X% z% J
  31.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_SET)        //判断按键未按下4 k6 x' w$ j9 E* H: _8 Z4 x( h1 ^
  32.                                 {
    : n7 N5 {$ E& x" I' |% c
  33.                                         keyState=KEY_CHECK;//回到检测状态
    / Q& z4 K% q- I" t$ F% l: G
  34.                                 //        keyvalue=1;
    % ?" q- H) K) A. E. }5 G$ w& d: O" I; l
  35.                                 }
    ! p; W5 Q% j8 w. S$ h
  36.                                 break;
    4 k3 A2 H# K% g7 S/ k8 v$ W
  37.                         }
    1 X9 N8 _/ O/ O2 `5 L/ @( V2 V
  38.                         default: break;
    8 d2 F. j- l! n% ^2 [' h% l
  39. }
    6 _! C  P; @$ r& H
  40.                 }4 \0 @- x- w# q, o' g( E
  41.         }2 E2 E9 k8 v4 n6 T& b9 F. D9 F. N
  42. /* USER CODE END 4 */
    $ j* ^" D- R) x3 f* S0 u( B
复制代码
+ ^/ g) H3 H6 v
主函数内: L# F& {% s( K5 A9 q
  1.   /* USER CODE BEGIN 2 */
    : P* X  z) P1 C0 @! T/ Q+ d
  2.         HAL_TIM_Base_Start(&htim2);//开启TIM2用于计数
    1 ]( _9 t; U/ y. K1 _" [
  3.         HAL_TIM_Base_Start_IT(&htim6);//开启TIM6用于按键检测
    / h9 E6 P& @; e5 Q) O
  4.         printf("Timer counter founction test: \n");//串口起始提示
    + D. \4 c+ K' K1 P2 y0 ^# x
  5.   /* USER CODE END 2 */. h( A/ b: Y' P6 x1 i1 f
  6. ! \8 O/ |# L& f) p
  7.   /* Infinite loop */
    0 T- _3 R! E/ q+ T
  8.   /* USER CODE BEGIN WHILE */% {; x8 Z# p, u: H  V6 @
  9.   while (1)
    ; @9 d5 j! {- L
  10.   {9 ~2 n7 t" x8 h% x: k6 x9 |$ W
  11.     /* USER CODE END WHILE */
    1 V$ a- j* H$ E; D/ w' G% S

  12. 7 B+ c2 @  k9 }/ x" J$ Z
  13.     /* USER CODE BEGIN 3 */+ Z. D% z9 `1 `6 N/ {8 j
  14.                 if(keyvalue==1)//如果为按下状态
    , G" [  j& V, v$ D
  15.                 {$ X  j' \- j) h* b3 ~
  16.                         keyvalue=0;
    - b9 J* [, ]% P% s( D/ d
  17.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);' n/ z6 ]) t' _
  18.                         HAL_Delay(1);
    5 Q: y! u$ I4 H! ^# N$ ^. a6 _
  19.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);+ \% z; a, Z9 G# H/ l% b  F& g% q  S
  20.                         HAL_Delay(1);//发出周期为2ms的脉冲
    / K( s% ]1 C& F% h/ ~
  21.                         Result=__HAL_TIM_GET_COUNTER(&htim2);//读取计数值
    4 Z4 i0 ~0 j& F. X- k
  22.                         printf("Counter:%d.\n",Result);
    5 k* {1 F; I, g# @, l
  23.                 }
    % `! }# H6 `& r  E/ `! D
  24.   }( @! y9 Z, g$ c5 x
  25.   /* USER CODE END 3 */9 I6 o* \& I4 \7 {1 k7 X
复制代码
0 t; a2 [" P4 a5 d6 k2 P
CUBEMX配置7 g' N5 ~0 N' W+ X1 w  d
1.时钟配置外部晶振,主时钟为72MHz5 y) y$ v9 J3 d" Z$ y

6 o- b) b: x- ~
979c22c7e76f4ab78bc893bb547e198b.png 8 j/ W' L3 {8 W/ Q/ N& S) K; S
, l, x0 o" n9 `+ P# L
34c3cc70065643e0a83680e530b4fa1f.png
" u8 x; q' c$ K' f+ R1 q
+ D5 G) t" Z2 P
2.GPIO:选择PA1输出,PE3输入, c# n5 o9 t& a( G; g) Y

8 ]5 b- m7 N- u1 ~. ?5 ^( Y
99ee5bd1a11d457b882ae5e5351cf12c.png / k% |+ i8 X+ r1 y% c& |; o

& V6 o/ }6 r0 Y9 n4 S6 k3.TIM:) |; H/ E1 q+ m, `
TIM2:Clock Source:外部触发5 ]  y+ I& \; h0 a7 @! [
5 @3 U- V9 @% k: W& W% [6 }. W2 h* W
dff3c1e441b548fd8fce92e0c69cc35f.png + b7 g: q+ f7 ]/ j3 W8 A7 ]9 R$ u) _) G

+ t; u/ m: c4 |  a9 s这时PA0为你的触发引脚& o+ {! r7 b8 J
: H; B6 V( E# X' h. F0 r
c4b66361f77d4f38a0683db19bedb4ce.png / X" g# P, E/ k# |7 P2 O; `1 |! w

$ q0 ^+ m8 `+ s3 K" i2 I+ V2 L6 ]TIM6:激活并生成10ms中断
+ m# z$ i6 d: F1 d! z' ~( B
4 w. c- B# H% O! E* m! c' _- h
6eeb551aeaaf4abda7027fe83d121b43.png
1 j( Z2 ]/ P) w$ J8 S

7 c2 w/ _3 L0 x0 w. u4.usart设置
8 |( d" y! {6 h% |
: `, x9 f& |+ @. k9 Z  ]( d
a6749464d8264738a2744efc34c42a99.png
4 I0 X3 C  m, \9 u' Q; K  s2 u1 e. J
5.Project的设置,
# N+ C, o; z; _+ f0 J: [$ O- ~; e! {0 a' R! G& h
e25a54d171e6456e9606191ea4a2796e.png . M) g1 ~& K5 u1 @$ _! W2 S

9 j2 I1 U$ D) R, p还有一个之前没注意,就是在Code Generator一栏中第一个方框里选择第二个:Copy only the necessary library files,要不一个工程就是百八十MB,占内存。
3 z( X: }# X+ y; ~, {& W
& s* K4 ]" x8 I) Z% l
a29154c1ca2a4f3587b8d571a6a4f741.png
8 R, j+ O6 H$ n- N: N0 v7 u% [( x# G! u
最后生成代码( j8 B7 N! s) A* N& Q# W9 A/ ]
————————————————$ u- x6 R! i& E- l
版权声明:南山笑
1 h" M* m2 U8 F. V如有侵权请联系删除2 ]1 O1 K3 B7 y; K/ u& k

8 X$ A  l/ t+ @4 u/ g
7 P) ^$ t3 S* h& Z6 [  L) {
赞 收藏 评论0 发布时间:2023-5-17 17:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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