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

如何解决STM32按键长与短按的问题

[复制链接]
攻城狮Melo 发布时间:2023-3-17 17:30
Stm32 解决按键的长按和短按3 P* Z; Z% c7 I( y" v, v# D$ X$ k
废话不多说, 直接上干货 注意:本文是采用Stm32 HAL库编写, 可以移植成库函数, 其原理是相同的!!!!' H/ g3 I1 E' A  B# I6 J
第一步 : 首先在key.h定义几个变量
  1. / 按键的键值, p' W0 @2 O5 \
  2. #define KEY1_Press 1
    / ~$ T- Y0 \' p- [$ b- s- b1 J
  3. #define KEY2_Press 2
    $ l/ `  F$ \; b' f
  4. #define KEY3_Press 3
    5 [9 U) X  u6 w! E
  5. #define KEY4_Press 4: n1 k7 a$ F) h4 l5 i

  6. " ?. L4 s3 ?9 e: W$ f
  7. / 读取IO口的电平' l4 V+ ~: v/ q" x
  8. #define KEY1 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)
    6 G6 O9 }8 i$ Y4 I% S, U
  9. #define KEY2 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)
    : u( u0 d, K7 V: q
  10. #define KEY3 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)0 E( u- Q9 w4 I8 G6 Z$ {: h1 i
  11. #define KEY4 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)( t7 q3 a: c0 I: m" N% p+ m
复制代码

" l3 r! Z9 r& j9 d. }8 ~$ N第二步: 在key.c 中编写按键扫描函数
( H$ G9 e6 U1 O4 x# v: ^
  1. <font color = blue  size   = 5> 编写的按键扫描函数, 只需要返回键值即可, 不需要我们判断按键是否松开这些情况
    8 x7 H2 Z# }) e( Q2 d3 n
  2. 3 I7 ~$ R3 Y( z  J5 i( S
  3. uint8_t KEY_Scan()
    ' w% K. Q4 G  [/ [
  4. {
    * U( b) l9 H0 M8 ], Q; x# E# z$ E5 l
  5.         if ((KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0)) 判断是否有按键按下. ?6 H. P/ Q2 \/ K5 U' ]
  6.         {
    9 S6 [* I! m9 d: [7 ~& B5 M
  7.                 HAL_Delay(10);  消抖, I+ X+ q$ a( n
  8.                 if((KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0))/// 判断按键是否按下
    ( ?; o/ P, u# e% Q0 B$ g
  9.                 {# ?! S! n& p, p( G6 Z8 b
  10.                         if (!KEY1)  return KEY1_Press;/ 返回键值
    " T3 f, s( t. ^; q/ H
  11.                         else if (!KEY2) return KEY2_Press;
    7 |5 l# h, n$ |* o, t3 y! v/ r
  12.                         else if (!KEY3) return KEY3_Press;
    . p" x& v) H2 X0 w  ^) t
  13.                         else if (!KEY4) return KEY4_Press;0 w& ?& U0 R1 G; y& N
  14.                 }
    9 W* R1 I  E) N
  15.                 ! z& k( y5 S" r$ Q! a& h7 x
  16.         }& n& L' i  e  Y* R  K- C, Y) \  ?
  17.         return 0; / 如果没有按键按下 返回0
    ' u! g5 U6 W- Z8 p0 P" c- Q& Y
  18. }
    4 G: @: D7 x0 g1 P& D5 ]0 J
复制代码
6 y3 L/ H. `5 Y: h: l/ j% c

) W! s  q; z( b, g/ }3 z+ T: v  Z4 V0 }三 编写定时器(1ms)
: y4 ?, [, R! b, }- {这里我们认为 当按下按键的时间持续 0.8s 认为是长按 !!!!, 需要开启一个定时器和2个记录时间的变量(key_last_time, key_now_time), 为了快速配置, 这里我们使用 Stm32cubemx 配置 我们还可以设置长按的时间来设置不同的状态, 这也是实现仅一个按键可以实现控制多个状态的方法 我使用的板子时钟配置为80MHz, 配置 1ms的中断,
. |! Y& `* p" E, g/ R
) Y- q! ]: s" N2 I
e1591aab2a9c4328a80b9e9bf769cdb2.png " s4 u2 |, N. z! o/ p

/ q. N+ G* g/ `, Z
68b29802ea884decbea7e2b31eda819a.png & X7 i% Z1 g) ]2 v. D
# N( I, N1 K* l, W
6c3a1981ce9a42c8a884109d621897d0.png
, i3 F. ^3 _# X/ X: `

% `* a, B4 @5 Y2 f接下来, 我们只需要 让key_now_time变量在这一个定时器中断里面加1即可) n, t* @! e8 H9 p

& W2 _* ]- F. h" Z+ M$ b
868249bc1ace4ff7b04497ffdc6f4bc4.png , L+ P& A+ @, n
) u* k+ L* @0 z# W
  1. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)  1ms的中断
    - v' L$ P  J+ j/ @& Z! K1 W0 ^' e
  2. {
    4 B2 Z# m: S) `# D5 Z  x0 }
  3.         key_now_time++;8 y$ h# U7 F$ w- g
  4. }9 X+ I$ Z; I9 O4 M: ?6 t+ u
复制代码
$ R; k# B+ \; e
四 编写按键处理函数
" X+ j: n2 Q4 E, r( \- Q. |( I: L) r
9 q* Q2 O9 s5 ]" ^. R% V
35745434387344c59c6ec20cfd09d83c.png
$ `; q( @4 T3 k9 e) Q

- i/ R  ?+ l( d! O# y  s) b! i按键处理函数:
0 R0 h! R. E0 |
  1. void Deal_Key(void)" }1 F, V8 s0 [/ g' s, [: l& ^
  2. {- K4 f# F# B+ |+ S
  3.         uint8_t key_value;
    # F( R8 n7 n& @3 D& c: y2 W3 }+ S
  4.         key_value = KEY_Scan(); 获取键值& @+ M+ d  Q4 y8 Z8 W
  5.         - J& Y$ E. R2 ]2 Q( y% q/ v
  6.        
    * M4 P# [1 d7 D
  7.         if (key_value !=key_old )  H0 M2 I, g! W1 H9 O* |7 K9 N$ X$ A
  8.                  与上一次的键值比较 如果不相等,表明有键值的变化,开始计时
    9 K7 x8 w* c! v+ u, P$ z
  9.         {
    3 z" F7 h* ]$ S5 t
  10.                 : U% m$ m  z# B) S& X
  11.                 key_old = key_value; 更新旧键值
    ' s- c2 W2 ]( h& Y! E( F
  12.                 key_last_time = key_now_time; 让2者相等, % Y1 J8 ]/ q9 h5 U8 q: S
  13.         }
    & t  O$ b& q2 K8 a4 ]4 f  H  v% j
  14.         else
    ) N! M& n+ k: D7 j0 H3 V
  15.                 key_value = 0; 如果没有键值的改变 说明没有按键按下或松开
    ! o9 f* P! S8 ]: p, {" Q7 Z: o, `
  16.        
    0 O4 r5 E% n2 M3 `* `3 o, G  @
  17.         2 q& |& q! e4 h
  18.         if (key_value)/ 短按处理 ; T3 O5 G& l: t3 A: P4 r% m6 |
  19.         {
    / ?: v8 k6 b5 N0 t' w# q# R
  20.                 switch(key_value)
    , n2 N8 y# {5 `! m6 r9 s$ `+ r# j
  21.                 {
    9 Z" H+ w+ o, c9 f
  22.                         case 1 :   printf("KEY1 按下\r\n"); break;
      o- h" c  I! Y3 t
  23.                         case 2 :   printf("KEY2 按下\r\n"); break;9 R" ?6 B; _( o8 L! P/ y
  24.                         case 3 :   printf("KEY3 按下\r\n"); break;8 u$ S# t4 w. S1 q* T( }- M/ R( n" m! O9 m
  25.                         case 4 :   printf("KEY4 按下\r\n"); break;3 M9 {$ k4 o7 P. k( A0 \
  26.                 }
    " Z8 w# L  j" _/ t
  27.                 key_value = 0; /// 该语句可有可无, 为了保险, 最好加上
    ! ^* z, a/ w7 I2 [
  28.         }
    3 ?  W0 [% Q1 K/ A
  29.        
    0 c! ?7 ?$ m2 |* g6 Z0 B" X
  30.         2 @1 l* K- a) `3 Q* @
  31.         if ((key_now_time- key_last_time > 800))/ 如果按键按下超过0.8s 判断按键
    ( y. z+ `3 P+ i' A
  32.         {+ O* F  l0 I$ e9 W" f3 |) U
  33.                 if(key_old) / 注意 一定是判断旧键值, 因为当按键一直按下未松开时, 即key_old == key_value,9 |; a3 F6 j3 x+ z
  34.                  此时key_value 0 ;# M& u* h/ K& Y/ U
  35.                 {: R! m7 M! j9 d4 j1 J! ]
  36.                         switch(key_old)
    3 t$ t4 k9 p) |8 ?' B  m1 n+ f
  37.                         {1 ^! F" v, w) p4 |; F9 {5 u) t, V5 B
  38.                         case 1 :   printf("KEY1 长按\r\n"); break;3 u3 j1 r- g& `, a0 t
  39.                         case 2 :   printf("KEY2 长按\r\n"); break;
    " W; V5 M) y( P% H) O9 x
  40.                         case 3 :   printf("KEY3 长按\r\n"); break;
    - [6 I, V5 [8 L
  41.                         case 4 :   printf("KEY4 长按\r\n"); break;. z" V+ ~) O6 h
  42.                         }
    ( R" V! c' M7 k; \0 F
  43.                 }
    8 @  D& n2 `5 k& E  N# w
  44.         }* \. \0 B/ C8 K) z) r) k5 R5 \
  45. }% ~0 X# ^1 ?* D: f2 w
复制代码
! t6 u3 W3 {4 T" s+ s8 Y% q
接下来, 我们只需要把按键处理函数放入while(1) 大循环中即可!!!!
$ J& x" k9 \! t: s: j9 T; W. T$ h7 z0 r: X
edf053d1fdda48619f88d3ec34db8fd6.png 7 A, N' N8 L4 C( j

9 G' M. H. @2 ~/ R4 Y, N6 k————————————————
7 c2 @" X, f4 |8 g6 C4 N: s( {版权声明:YELLOW_YELLOW_YELOW1 J' p8 c% t5 s( M6 E( Q
如有侵权请联系删除( b! f% |7 ]% T" X! U5 J2 F6 r6 j6 H
5 s6 E! E9 s9 H+ a/ z7 l9 k
收藏 评论0 发布时间:2023-3-17 17:30

举报

0个回答

所属标签

相似分享

官网相关资源

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