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

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

[复制链接]
攻城狮Melo 发布时间:2023-5-22 18:34
之前我们用外部中断测量了PWM的频率,而外部触发是设置2个定时器,利用按键触发,一个定时器2用来接受外部触发信号并计数,另一个定时器6实时检测按键。
5 H) |" E8 Z0 _; ~# V按照这样的思路,我们的按键读取用状态机思想去读取,使定时器6产生10ms的定时中断来实时检测按键并利用状态机设计思想处理按键信号,将PA1设置成输出引脚,设置定时器2的PA0引脚来接收信号,通过按键触发改变标志位来发送电平信号,再定义全局数存放PA0接收脉冲信号次数,最后串口配置。
( l3 B" E0 {6 `
. i9 x' o) r9 _: u说实话,状态机思想可以清晰把你的代码逻辑弄清楚,这个是我自己写按键时画的草图:% }5 `. V% H. B6 @$ P
: s" u/ L9 G" U( r0 u
9 [. D9 I- C, j  f$ N. f! b, ^4 a
1c7af8ac65064314a19f83d273578e06.jpg 2 X0 @2 C  k. u% }" v# e
+ W2 m1 {0 U% L/ o! M) ^. B! f  y

' n" a* U3 N/ ]3 X# f; E% p, A8 {画的只要你自己可以看懂就行
1 O. a+ w6 W" U" X) M
1 L0 Y0 m5 }. L; k6 O; m* `

+ C4 x6 D) T0 B8 W3 c$ B代码讲解$ D/ N  b& Q& F) Z4 R, {
首先我们需要按键的状态,它的状态分为检测,按下,释放,所以定义枚举类型的结构体( a) r, E" ?# J" {4 D
' Y" ^# L* d$ X( h$ I' `
6 N9 L4 _; Z3 Y+ ^6 g/ ]
  1. /* USER CODE BEGIN PTD */# l1 Q3 L5 {) D. z2 \* h
  2. typedef enum" y' d! |' v# r1 |% s
  3. {
    , i* {% E: x0 S4 W0 Z/ V* E0 a
  4.         KEY_CHECK=0,
    4 ^7 T( D3 Y8 l0 V0 q
  5.         KEY_CONFRIM,
    * \7 {' h, i+ B; F
  6.         KEY_RELAESE
    ( J: B1 @* U6 [, M. I6 U( \" ]  f& K
  7. }KEY_STATE;
    6 r& m* V- r% P. y
  8. /* USER CODE END PTD */' k( a8 h) T& M! P
复制代码
6 P# h( T/ d% i
状态变量的定义以及标志位,计数值
! K. K* ~3 V0 E1 t& p
6 h0 _, g; U; B- X1 e1 F0 a& \
$ m1 }2 J4 F. W  b8 l$ M2 C
  1. /* USER CODE BEGIN PV */
    # ]5 O  p4 A- u! S0 M
  2. KEY_STATE  keyState=KEY_CHECK;
    + e& l$ a# q1 O5 d$ y
  3. int Result=0;, j5 D4 W1 T3 _! e; l+ d9 v& C
  4. uint8_t keyvalue=0;
    / K( F! |! Q- ?
  5. 0 I* F  \8 [: E( g) P' q  i. i: q' `
  6. /* USER CODE END PV */8 _+ \) X+ v! ^/ Z% C/ S& c$ u
复制代码
) k0 |% m; v# a2 b9 ]& x# x
对于按键检测,是在TIM6里处理的,选用KEY1即PE3
: I% N! s: s$ j: `
1 U  g& F2 e' Y* M) x  J2 l1 f' h
! ?# |  C8 l$ ^1 I5 k- L
c310f614ea674bd7a36bab52fe7556e9.png 9 J8 ?) @" D- z

7 v6 L$ O% l* S% L
; x& i5 l# s- M# G3 }; e7 m# P
0d925669e44a45d591c29f341f0f0b45.png 5 E" y; I7 |) c) m
; l. L5 o8 x/ _

4 i3 C0 W# }% A) o% U/ k8 g而之间的状态转移是通过判断电平实现的,按下时为低电平,未按下为高电平,根据我们按下的一个完整过程,我们可以通过switch语句实现我们的整个过程
' j! A, k/ l7 Q& ~& B
# e7 E; e9 N, q+ V2 f  _
) Q. R  l+ c! p
  1. /* USER CODE BEGIN 4 */3 y2 a' [1 o# I4 p
  2. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)/ ?' X/ k: j0 c9 h9 _8 e( B- z
  3. {
    5 o# D. H) v8 w$ N2 A
  4.         if(htim->Instance==TIM6)//判断是否为TIM6中断
    : E6 {8 Q4 t2 m+ z+ J
  5.         {/ Z- `6 R6 Y2 d& y
  6.                 switch(keyState)
    9 @' b) [! r& D/ V2 ]" \- _" o
  7.                 {
    8 U" ~: Q: e2 N- f
  8.                         case KEY_CHECK://检测状态下6 _% X2 t6 _) v- m
  9.                         {4 v9 h/ {  T5 L7 y' ^- g2 e# ^
  10.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//检测按键为低电平& L! l' }! ]8 S" ^9 A5 G
  11.                                 {
    3 h+ B2 n/ P" j
  12.                                         keyState=KEY_CONFRIM;//确认按下状态
    / u" i' P. y, X
  13.                                 }: R; Z9 G' o! o% C) {1 O
  14.                                 break;
    . K, j: J# p+ F1 J
  15.                         }
    0 w  u  W5 F1 h8 ]( J
  16.                         case KEY_CONFRIM://确认按下状态下% N) t! d. _& \, _6 e3 f3 x
  17.                         {+ T& r# Y" }  o; e) a
  18.         if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_RESET)//再次判断        6 S# \7 N& C/ g" v% ]! _! M
  19.                                 {% d* V$ _% P* `5 w4 Y/ k
  20.               keyvalue=1;//改变标志位用于触发脉冲信号( n6 S7 a4 C; P6 o( ]1 K; W
  21.               keyState=KEY_RELAESE;//按下后释放$ @. r# t- y3 d/ a' {
  22.                                 }
    ' G$ \! D( e4 Q" S, d; D
  23.          else               
    ! ^- t, p* V$ B
  24.                                  {
    ( w; q" A4 w# R' V! B; m. K3 w
  25.                                             keyState=KEY_CHECK;//排除抖动干扰或者误判,回到检测3 V4 U/ c6 S* e0 p
  26.                                  }
    8 P" o3 D4 ^* ]8 a
  27.                                  break;
    & F- G9 q4 B5 k0 L: C9 S
  28.                          }4 S& ~3 j2 S+ ^' B# H8 h
  29.                         case KEY_RELAESE://释放状态下
    $ C# c3 w* L* a6 P8 P& _
  30.                         {  O4 c) S- r) B0 q
  31.                                 if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==GPIO_PIN_SET)        //判断按键未按下2 r  b" a* Z( n1 A- Z0 ^
  32.                                 {: J) q3 g' n$ v3 s: o' L
  33.                                         keyState=KEY_CHECK;//回到检测状态4 W6 X" v  {/ r& I; a( X! e
  34.                                 //        keyvalue=1;
    7 ?& I' T: A% J5 a9 |' V% Y  ^- }
  35.                                 }
    ) L* X+ e' I# Y) E7 ^
  36.                                 break;
    ) c  N9 i# o: [
  37.                         }
    $ g& a, Q. F& ], l  b
  38.                         default: break;; I  A" N7 |: G4 M( X/ T( }
  39. }
    , a$ v% ]& T" c5 n9 p
  40.                 }
    % K, G% `' O7 k) a# o4 a5 [
  41.         }& _( O" E0 j! ^: E' z! _- h7 Q5 C+ A4 ?
  42. /* USER CODE END 4 */" b9 X' ?& H/ n  B) y
复制代码

. K9 J7 P  V" @! X6 r. ?主函数内
! D0 K( w3 @9 H  E0 X
  1.   /* USER CODE BEGIN 2 */2 q9 W3 m; i( B% w& |  P
  2.         HAL_TIM_Base_Start(&htim2);//开启TIM2用于计数
    4 e/ C9 K+ n+ v* _1 S6 C; s/ R
  3.         HAL_TIM_Base_Start_IT(&htim6);//开启TIM6用于按键检测+ D  a( H3 d' v( p0 p2 |0 V
  4.         printf("Timer counter founction test: \n");//串口起始提示
    2 s' z% H$ P$ h' `4 t# E
  5.   /* USER CODE END 2 */0 x& c# k1 n7 `% g/ ]! L
  6. : S5 V, @* O/ j
  7.   /* Infinite loop */
      P/ j5 L& B% m3 ]1 q
  8.   /* USER CODE BEGIN WHILE */
    ! j' y6 P( V- e& O; h9 v6 l
  9.   while (1), r* N* G+ v+ X, J. P) J6 i/ E
  10.   {
    $ r8 L9 ?9 c3 z" J- R' \# N
  11.     /* USER CODE END WHILE */
    ; z+ ?* {( a2 I

  12. : `  q7 w3 s( n/ R& Q' E; V% t
  13.     /* USER CODE BEGIN 3 */9 K! G' }3 h& M0 ~# h: R( G9 S& H
  14.                 if(keyvalue==1)//如果为按下状态! m6 p+ [, R+ U0 J3 M; I
  15.                 {% D+ a2 }; ?. Z+ A5 o+ h
  16.                         keyvalue=0;
      Y' R3 g2 Y9 e( Z# V$ I8 D
  17.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);
    * `7 L$ e( B5 f- z/ {4 h" G3 c/ z
  18.                         HAL_Delay(1);8 D* ^/ Y& b7 p) R" q
  19.                         HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);
    # n+ U/ E4 {* G: q# T1 r
  20.                         HAL_Delay(1);//发出周期为2ms的脉冲
    2 S2 n7 r6 Q6 |
  21.                         Result=__HAL_TIM_GET_COUNTER(&htim2);//读取计数值( d) L7 K0 D$ {- |
  22.                         printf("Counter:%d.\n",Result);. }0 m# K* q' @# l* |+ t! @
  23.                 }
    4 S5 y" S( H8 K$ J1 b3 z
  24.   }
    2 X5 M! Q0 ]  T# w4 B0 [
  25.   /* USER CODE END 3 */
      r- X% D. t* k  j( @$ B/ {# s
复制代码

3 J7 X, H% M9 d# X+ A$ O7 o$ @CUBEMX配置
! K2 ^# K8 |* c7 V) ]9 I) l1.时钟配置外部晶振,主时钟为72MHz
9 N* a1 K$ w# U8 Y7 O# V) C  m& j; z' j( l' \& v$ Q
' n$ B4 y2 G, l5 i% m$ b! E
979c22c7e76f4ab78bc893bb547e198b.png
; p  a3 U8 d' u% S7 S8 A) C/ ]
& p- b( }3 ~# u' P0 r% u* Q: x 34c3cc70065643e0a83680e530b4fa1f.png + ]* ~4 H7 f$ d+ F9 _' q. M0 a) n

9 v3 h* ?% \% @8 L

! _6 ?, c: O4 v7 q7 r; Q2 J2.GPIO:选择PA1输出,PE3输入
. F4 m: k6 U. u/ L/ D% V9 J& \' K2 g

& ^( u. X& D# p+ W% w+ m 99ee5bd1a11d457b882ae5e5351cf12c.png   J+ ^: Z! r4 L& i$ _9 A* W/ `/ q
  L3 P2 X- q: C5 [# ?- @

2 @/ w# d; ~4 P  }' W) o3.TIM:0 F1 ^# j% s9 y! X, U! r4 }& h
TIM2:Clock Source:外部触发: t* A" N# M- H/ O1 B$ D

( b2 T# N7 z8 s2 w7 |& E7 d  [

) l3 q9 u: ^1 [; k# Y4 F dff3c1e441b548fd8fce92e0c69cc35f.png
1 L. k8 ]: d0 n2 w
1 d6 ^5 F- g! @2 K& K7 Q
6 p+ ^+ }8 P9 n6 m: M
这时PA0为你的触发引脚
. a4 i' \9 f! }; [' v1 W7 j9 B) {; w, ?1 F
& i) W; h0 v- Q1 x0 w, B+ P
c4b66361f77d4f38a0683db19bedb4ce.png
+ Y/ ]4 A: \4 E: u( P& A8 O( a! G2 b8 b2 ?$ ^. J
! S  n% m  k( p5 E* E6 ]) v
TIM6:激活并生成10ms中断3 j* _5 \5 f, g8 l2 }0 S8 o6 P

5 A3 J0 s: Z2 B8 O1 N% O
5 u: E' ?% `2 N9 A
6eeb551aeaaf4abda7027fe83d121b43.png $ t+ ?, C% U, X4 ^7 |3 e/ {

- p* Q+ S( j1 R6 e) `6 d

2 x2 T) r$ }: `- {5 j- L2 j4.usart设置1 o" s( p3 |$ }* ?" A( Z2 Z

% l3 Y/ P0 q/ }# J- y
, g- c5 W/ ~% a. Z# f5 D
a6749464d8264738a2744efc34c42a99.png
6 B6 l0 |" |( x2 {+ ?% h
: _% A* h. a% q

4 v, D: ~; {* _2 Y1 P: Q; ]7 z7 V) `5.Project的设置,0 S1 }# B  w% d) y# X$ m9 p
1 O' Y& G1 W, v0 u6 Z5 u: e
$ Y; `; W9 C& b* Z) s9 p8 Y
e25a54d171e6456e9606191ea4a2796e.png   P; o4 r! |+ T& A' }1 g
5 ^3 ~3 l3 q4 {& ?6 e! {& ~
' V- [$ {& r5 ]' a2 r  r9 J
还有一个之前没注意,就是在Code Generator一栏中第一个方框里选择第二个:Copy only the necessary library files,要不一个工程就是百八十MB,占内存。
$ n1 E; E) m; l/ d+ h/ K) j
( j. R$ m/ l6 K. v4 y
9 a$ i4 t) t: v) C& e( r& A& F1 F$ `
a29154c1ca2a4f3587b8d571a6a4f741.png 4 p* m% C9 P: E
+ q3 o0 ~+ x' v
4 u4 `* W/ d5 Y3 U2 ]! r3 f
最后生成代码
2 h8 }0 V% ]8 O; a) w————————————————, H5 e% H: v# Q# G# q
版权声明:南山笑3 K0 }: k5 S% O* O- I' \2 J
# a$ e7 Y- p  t( j
如有侵权请联系删除
9 a7 N) Y( }% x
' ]0 K) u0 G; I& Y& f; }! ?- ]# |9 r! e
收藏 评论0 发布时间:2023-5-22 18:34

举报

0个回答

所属标签

相似技术帖

官网相关资源

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