Stm32 解决按键的长按和短按
6 F& ]3 y& Y6 [废话不多说, 直接上干货 注意:本文是采用Stm32 HAL库编写, 可以移植成库函数, 其原理是相同的!!!!
+ O4 ~; X& ~( d* f2 g5 i( T第一步 : 首先在key.h定义几个变量- / 按键的键值" d& A/ b6 E1 X, f9 ~% F
- #define KEY1_Press 1
& H: X" ^' ]5 I* H# [5 ` - #define KEY2_Press 22 r' d$ C+ u, g. ]7 P" Q% I- l2 g
- #define KEY3_Press 3& n$ ^( F) O- J
- #define KEY4_Press 4
4 ^7 |9 h- ?- N1 W2 s
3 f$ ?: D, J8 W" d% d0 r- / 读取IO口的电平) b; K) h/ V$ L8 h4 `0 W8 D
- #define KEY1 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0)& H" z9 [& Z1 y1 G* p
- #define KEY2 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)) _" g3 l& Z8 c. L
- #define KEY3 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2)
9 a9 k7 R# C2 R+ r. {) u - #define KEY4 HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0). Q' m5 S( c. q% v" X4 v5 y
复制代码 5 ]; y" |' y' K5 q/ J( |3 i
第二步: 在key.c 中编写按键扫描函数6 z# e' D w/ a, Z3 G, |" T
- <font color = blue size = 5> 编写的按键扫描函数, 只需要返回键值即可, 不需要我们判断按键是否松开这些情况
5 l* j( C" }+ w2 u+ y - . A4 m- n. i: h2 h3 S
- uint8_t KEY_Scan()# W f) g8 R7 q3 q4 M& e
- {
7 F6 u) P3 t% {* Z$ h2 V$ h - if ((KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0)) 判断是否有按键按下; i z ?1 U# V |8 q
- {
" @# P: a0 o0 {& x3 K7 M6 h - HAL_Delay(10); 消抖
3 c% ^* M5 v# [ - if((KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0))/// 判断按键是否按下7 H" g! ?, H% p/ m3 A# r! ] ^5 w
- {0 v, J7 r7 h, \) E7 k. d
- if (!KEY1) return KEY1_Press;/ 返回键值
* g# M: x7 }2 X3 M - else if (!KEY2) return KEY2_Press;7 i$ Z1 W# L- `' |# Y( f1 J9 V& ]
- else if (!KEY3) return KEY3_Press;
1 B1 w% _ i" k5 o/ Y( b W - else if (!KEY4) return KEY4_Press;* s7 v- I- M$ z: n8 v1 U
- }' E% z8 |, j+ L, j2 }
- ! d# | r" T6 W- N' `) E2 h$ q, Z
- }1 \2 |/ p" u# ^8 k/ Y: e: y
- return 0; / 如果没有按键按下 返回0* p! O( j! I9 C5 b
- }- D/ Y+ {8 Z6 E/ W0 S/ s$ m; l
复制代码 - F( [/ Z0 G- I2 D) ~9 L' m
, I8 i' U2 \3 k1 p& y& h
三 编写定时器(1ms)
* h, V- s! u0 w! U" H; A/ z2 |这里我们认为 当按下按键的时间持续 0.8s 认为是长按 !!!!, 需要开启一个定时器和2个记录时间的变量(key_last_time, key_now_time), 为了快速配置, 这里我们使用 Stm32cubemx 配置 我们还可以设置长按的时间来设置不同的状态, 这也是实现仅一个按键可以实现控制多个状态的方法 我使用的板子时钟配置为80MHz, 配置 1ms的中断,( j0 b' q* X, g; a" h2 f) H
% y% q5 z9 V8 j8 \ b ~
7 t- a/ D5 w) o& e! N4 k! J3 i* |$ Z7 o
; H1 `1 O( |' s h" y2 p
7 O0 |. a/ |1 Q! P, T" l
' g z' _- L; s! q. U+ |3 v, \8 A
. g$ S( p; K! y4 B& V' j- P' W; r i4 S9 {
接下来, 我们只需要 让key_now_time变量在这一个定时器中断里面加1即可& m/ Y7 u8 k0 e* B* x" s! H$ q. M
! P5 T/ N1 h( m2 C
( B) t4 l" }( M$ q t
. v; K4 r5 z$ S5 q- void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 1ms的中断
, r2 H) j: t: M - {
2 b1 q% n- ? f/ A7 g; Z - key_now_time++;' i* j) ` C' a
- }
7 ]) l3 ?' G+ S5 }3 z, k6 _
复制代码
: _, u% P: I* J% C% l. c6 t3 p四 编写按键处理函数5 R( [ V; h! n- M2 u3 {# k
3 R( c) j: Z9 c
. K* \$ Q2 e9 _( ~/ M9 e
, D# x) ?) ?* Y$ I/ s
按键处理函数:
8 [0 e) P/ G7 r$ M- void Deal_Key(void)7 ]9 [" d4 K* E) J" T) j) U. z; N
- {( G% _8 ?! ?' Z% g6 D# @
- uint8_t key_value; 3 B4 R9 v% m3 {- c) W0 ^
- key_value = KEY_Scan(); 获取键值
7 v1 J G& ^% p. O& { - u1 R1 |- c2 F
- ( j$ ]' s2 A3 ^, G
- if (key_value !=key_old )
& {2 e9 z7 V( m: o5 G: S - 与上一次的键值比较 如果不相等,表明有键值的变化,开始计时
& y$ q! ~& c& Y1 r0 R7 X) ?5 l& u - {
. P( A; H- ]" m1 E -
; O+ f: k" g" F1 A: }0 t7 n" c - key_old = key_value; 更新旧键值
$ k! y3 A2 S/ O' U, k( e - key_last_time = key_now_time; 让2者相等,
, I6 _9 m: x# D7 _ r$ I - }. G( o! A2 \9 {1 `; w" k# D
- else
! B2 d' R' m6 F& V4 ~ - key_value = 0; 如果没有键值的改变 说明没有按键按下或松开9 r7 |) D: W: I2 g
- $ K" h% W: Z' t, r
- ( M% G- I6 c, E2 A8 N7 S6 ?6 P" q) r1 L
- if (key_value)/ 短按处理 % \1 @6 Z' _5 P5 a! q; r! n, I( F G& J
- {
9 y/ f3 T0 k' P& V- \& Z5 ~7 p, \ - switch(key_value)
" `6 N3 p1 Q1 Z* Z - { V9 p+ A1 f4 U5 k
- case 1 : printf("KEY1 按下\r\n"); break;2 ~0 F& E' G2 o2 } R# D8 |
- case 2 : printf("KEY2 按下\r\n"); break;- f, E3 n: ]9 j* y8 ?; N; d
- case 3 : printf("KEY3 按下\r\n"); break;
$ t" B' f. _/ w5 k/ Y - case 4 : printf("KEY4 按下\r\n"); break;, v* A6 Q( \6 R' D+ }# X
- }! X4 c# }3 r2 j5 j/ l
- key_value = 0; /// 该语句可有可无, 为了保险, 最好加上% d D3 E- ?- S' s( D- A7 Q/ T* O
- }$ E; S! O/ L4 y c
-
# Y& {2 }/ N7 L' _; g5 X1 O0 N* t6 p -
% I( W1 `% ^/ C - if ((key_now_time- key_last_time > 800))/ 如果按键按下超过0.8s 判断按键& Z0 y5 D* q. b
- {
6 w' K) i+ f* x/ t2 j" T4 ^ - if(key_old) / 注意 一定是判断旧键值, 因为当按键一直按下未松开时, 即key_old == key_value,3 n7 ~7 Q/ D( ?" t
- 此时key_value 0 ;8 p. q! Z& v# ?8 A4 ^7 c
- {
' N4 g; B( @4 _! v6 b0 v - switch(key_old)# e" ]( [4 q7 p4 g( W
- {1 z, H& b) w, P1 H
- case 1 : printf("KEY1 长按\r\n"); break;" ~+ a- N( n4 J' F1 N, N
- case 2 : printf("KEY2 长按\r\n"); break;
/ S0 u t) p& w - case 3 : printf("KEY3 长按\r\n"); break;7 K% h- d* p: X4 n0 c2 o
- case 4 : printf("KEY4 长按\r\n"); break;! M& q) \- _- V4 f( K9 ]
- }, ~ e( _4 y* c+ l( c, |" ~7 Q3 c
- }
1 @$ j2 k. @6 i% e E - }
! ~: c( U. E/ h* _ - }1 K* {( e+ J9 p; d L0 c5 S g y
复制代码
0 S8 E& y. M% [$ B# u R- M4 P% ]接下来, 我们只需要把按键处理函数放入while(1) 大循环中即可!!!!. D7 B6 ^( F& q% e7 {+ X; T
9 S- h( Z. Q7 N
3 A$ H5 d- W4 }
. q* p8 d1 m. C- c6 P# Y6 S, e———————————————— q, C) C( }5 G1 H/ x% z
版权声明:YELLOW_YELLOW_YELOW
* E- b/ ^3 q3 Z/ k- u如有侵权请联系删除
8 K& s) }3 I1 u- W
, G8 N& D4 ]/ | |