|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
51单片机按键检测源程序(实现单击、双击、长按等功能)
4 @ i' ?, a( C8 o, V2 {原理:将按键这一事件的过程划分成如下几个状态:9 J9 K& w# `, t! B9 G) F
//stata 函数运行状态" M6 q0 I* G: c6 `$ J3 ]# V
//0: 初始状态& j, C, C2 x, I
//1: 第一洗按键按下" L: W- }! h. m! t/ R
//2: 第一次长按抬起
! L1 g/ W! M2 \& a6 H. r //3: 第一次短按抬起
2 A: B, H5 E( d //4: 第二次按键按下
7 l5 S1 S% q' v //5: 第二次按键抬起' Z4 u- Q) S9 B
" b$ u0 d$ a, c+ t# _; j: n9 R3 Q利用定时器记录系统运行时间,根据系统运行时间来确定按键时间间隔,根据不同的时间间隔来判断当前按键事件处于哪一过程以及是否结束该事件。' T5 H U0 h4 m; s8 W* m3 g) t
主函数中应循环调用按键检测函数,调用间隔不超过100ms,此函数不会阻塞程序运行。4 q& P: ^) r) s, K* C3 W# e8 l" }. i
& b2 ~* s& L m$ d
- `: V! j% t9 X5 X: R
版本说明:7 `9 Q/ B% S5 s& ?5 W
............................................................. }' ^* E( i' @
版本号Beta0.0* k6 k) J. U' u
本驱动工具包主要包含以下驱动(xxx.c文件和xxx.h文件共同使用,下面不再写后缀); w c1 g" D3 M: ]5 f$ W
1“define.h”----包含了类型定义与开发板属性的设置(如晶振频率等)( ?; L0 w: O p! ?1 m9 y2 `/ z
2“delay”----定义了两个延时函数,支持STC大多数芯片(除15H系列..)5 w# Q3 r, }' w! o# U( F
【提示】本函数库中驱动多数依赖于"delay.c""delay.h"和"define.h"文件
2 z8 W3 J+ `1 _& z3“digital_display”----数码管显示驱动(硬件是基于两个373锁存器分别用作段数据和位数据)
8 o! m6 v7 c# j% K4“digital_to_string”----包含了浮点数转换成字符串的函数8 c% T: e5 N0 ~3 b+ N! v
5“DS18B20”----温度传感器驱动
& \# b5 h9 {9 b( `1 t! Z6“DS1302”----时钟芯片驱动: ]+ U }$ G: w, _# P" O: j
7“I2C”----软件模拟I2C总线驱动
\ I" T7 K6 e" `: K9 l. i8“Keyboard”----矩阵键盘驱动
4 R+ F' |( z) ]( L9“LCD_1602_display”----1602液晶屏驱动(并口)
+ h+ v% C7 p/ C7 r. r10“LCD_12864_display”----12864液晶屏驱动(并口带中文字库)(只是显示文字,不包含画图)
$ I# e9 k! l# V" L9 I6 u Q11“NEC_IR_coding”----用一个红外LED实现红外编码发射的驱动3 W6 b5 ~2 `, U; i: G9 s! W
12“NEC_IR_decoding”----红外解码驱动# k% B* _- i! \; [( f8 V1 v6 j
13“NRF24L01”----2.4G无线通讯模块驱动
% o! `( a/ S+ H& z9 L; |14“Uart”----串口驱动相关函数
' x) S* a0 \. W* u& H未完待续...
0 m5 W& c- k. Q............................................................
. J+ o# ]( O9 a& N- C( w............................................................
! @5 g; D" c7 A/ T# K* b9 [9 v版本号Beta0.1
1 }& W0 j& w: ]9 v( c1 r修复了数码管有关残影的bug4 z; D5 P: n% N
取消了矩阵键盘的松手检测,检测不到键按下时返回0代替/ w* Y, x% E# n8 c9 X& T$ m
未完待续...) X+ v6 i# G' X# U. D8 x
............................................................1 b3 }9 `; O0 U- V+ B* b/ R4 B
............................................................5 y/ `7 [4 B, M" e
版本号Beta0.2
( |! G6 E) h" c& ~8 \加入了独立按键的检测,兼容矩阵按键,修复了矩阵键盘关于不同开发板兼容性的bug' ~+ c* Q: ?7 Y8 T
增加了串口不同波特率的初始化程序% z \3 d$ g6 s7 }
未完待续...
6 S1 p8 v) [0 i/ I9 f% }2 K............................................................
+ J& O* E; Q6 [. f7 h5 u6 o9 f............................................................
6 n! g C% _- l% `' J版本号Beta0.3' Q3 h1 o3 K6 @. |8 Z3 f; N1 h; i
调整了数码管显示驱动的结构代码,方便不同开发板移植$ [( _3 B7 X6 ?
调整了红外解码阈值,提高解码效率$ s) R) J: ^3 P
未完待续...
+ F( q$ e: o5 h6 b$ N0 u! l( I............................................................7 U2 h8 g) M* Q
............................................................ ~# ?- `5 o V
版本号Beta0.4
2 e. S, Z' k7 S8 I: |. t: u1602液晶驱动的代码更改为区域刷新,字符串长度不够显示空格,避免出现显示残留
6 q5 _' v( M* P w3 A调整了若干驱动文件名字8 |; Z2 ~. e! N7 y% E8 ?8 n5 N! v+ t
修复了数字转字符串函数在显示0时有负号的bug
' U& g9 {8 g; q# J" W6 ]添加了QMC5883地磁场传感器驱动) o2 Y: [( T9 T8 q4 l1 h
未完待续...
4 x1 M6 b, C5 G* N............................................................
5 g! M* Y" a) e3 P. j# J3 @; i/ [1 R6 D d
1 D/ T- M8 U0 q
) F: i0 \0 O$ i核心代码如下:
T6 y1 x# O# V7 r
0 t; H4 b4 c" p2 M" c5 F$ `7 I( N! N. {- `& W
/*
' t) d# B4 k% ?9 n按键检测& f6 ?( }) `6 t7 {3 I
返回值:0 无结果5 v. w5 X- c4 d9 `+ e' L2 r
1 短按3 R5 n+ e$ z( |& U
2 长按
7 X2 f7 p7 b% R7 C 3 双击
2 L8 `4 n" i: R4 E) N3 O* l*/ v7 N S% S j4 l6 }$ L
u8 key_scan()
! q% ]6 {. ^. d5 ]0 t2 s% V{
3 G' b: T5 e; H3 N( v* L //stata 函数运行状态
' P* o, r* I* b" b0 [' a //0: 初始状态9 y) V, Z5 G4 r
//1: 第一洗按键按下
: F- d9 | k; B- V# Q //2: 第一次长按抬起
0 O2 y* e0 Y' \( h6 t, B+ g //3: 第一次短按抬起
q5 ^; B) Q. D& ?2 j //4: 第二次按键按下
& R6 G$ H0 \5 v t0 i //5: 第二次按键抬起
+ G+ Z( t$ T; B; k u8 res=0;* b" {( [ J2 e0 {' U: {! F5 {
static u8 key_sta,stata=0;
7 b `: Z9 T7 {% Y$ d/ n static u32 time=0,time1=0,time2=0;
& E3 R7 p- x/ N6 ^$ m if(key==0) //按下消抖( C8 p; `) J; u' l `+ p. A( E& F
{0 s M$ A; D- r$ y9 C
delay_10ms(1);$ G. O5 i& B" k
if(key==0)
L3 Q( k" {/ J key_sta=0; 3 d7 _4 M5 ]9 k* R" c+ ~ w! O" }
else
8 k) Q; K, I; A7 @& T return 0;
2 P/ j/ Q! q+ o, P+ F }7 f: ^. N0 D( N
else //松开消抖
5 b" }* ^2 i k& I1 P' l {5 M" Z7 |! k) l( X: h
delay_10ms(1);* n2 K; Y/ m8 k5 Y9 e( S9 E7 ~
if(key==1)
3 F0 H, p; K. Y; s key_sta=1; # Q: V9 u/ p4 q) t, K* E
else' o% E* M7 s- U
return 0;
7 p+ z9 v4 p |5 i3 P* l }/ s( _. C0 y k4 O; ]
2 |' X$ k S& h! a; K1 L
if(stata==0) //0: 初始状态
4 G1 c' n1 C, c {
" `( ^, g# n$ D9 G- [ if(key_sta==0)
0 h# C& u5 s# ^ S: o' ]0 g {
( X7 [" ^: w. I, f4 ? stata=1;
& V7 y- o' R% l: t- L) }" | time=system_time;
9 k0 X) P: ~1 A }
" v( n5 @: J: |; V' q. k return 0;
' Z4 J4 q! n# n9 g$ \ }( O9 z; E: i) o! ^" t; @8 R" c
else if(stata==1) //1: 第一洗按键按下2 j8 w0 v4 L5 R6 q" b2 }0 t( a/ _
{) W- l" S5 P. A& q1 c: Q9 p
time1=system_time;7 r9 X/ A! }$ F2 }; O
time2=time1-time;
& O4 S) g! d5 R g) |! L$ x if(time2>60)" d0 i/ j% a# h, P) M$ x
{2 y' _* _ B* Y! B7 i& {9 X
stata=2; - A+ y- t( i; s
}5 O' ?* V/ g9 G1 c
else if(key_sta==1)
- P& l+ L: r, F$ M3 z {, }* R3 _; T# B! X
time=system_time;
9 I% g9 H, w% k& k+ K stata=3;. ?7 O) V e& C! o a/ H4 Q
}; j7 x5 ?5 w3 C, o
return 0;
* G6 ?/ I- L" B' p' B- e p9 z }
* C, |9 G7 m: v* v4 w6 s( Q7 C else if(stata==2) //2: 第一次长按抬起( F: E) j: b' o$ H
{+ c; W9 M$ m3 e% Z! z" n( j
if(key_sta==1)6 g+ {4 Q) B6 q) @# b
{ . H& e% v( M$ x# ^, X
stata=0;
2 C' z" k; r5 {/ v3 f6 k+ E return 2;
# M' W5 A7 A# k1 L7 u" S/ Z }2 l+ L7 j1 x: w4 x0 \# s# ]# U
return 0;
$ `) U, R+ j N }
9 b. i6 `) \( Y, A; I else if(stata==3) //3: 第一次短按抬起
# o. R0 z& `7 T: G% S {
/ M! |( I, {; V5 v/ @8 X time1=system_time;
7 t# e* u- \3 E8 } time2=time1-time;; E2 C+ E; ~9 w' z: M4 W5 N3 h1 J
if(time2>30)( S1 f" C$ M8 J7 l! c
{2 A7 |; ~1 @6 {( K
stata=0; 4 V# U9 A, w3 m! ?/ f3 H
return 1;
* u9 F& I$ ?: @4 {$ K z. }* m }
' Z& G+ c3 w) F* p: L else if(key_sta==0)3 I3 p) d, Q p% T" y
{
: Z" g9 T% O& M; I! ~ x* a% _ stata=4;
( A3 R/ c0 t/ G, C3 Y; z) S }. l, F; e M6 y
return 0;
6 b) w3 T7 \0 X) L; P }
& V2 Y6 w; l' m+ W4 L4 n else if(stata==4) //4: 第二次按键按下
7 x+ q; R0 d& [# O( q: s7 {3 m {. S( w" D; n" i* g5 @+ ^* x
if(key_sta==1) //5: 第二次按键抬起3 E" |8 X4 G7 |
{
. Y% v) Q+ T: H7 q" w6 r stata=0;0 w% x/ ?5 S5 X) E& h$ Q$ {" a2 D
return 3;
3 C0 [' P. @9 H+ t- D }
. U D3 i" Q% j" x return 0;
1 e7 M$ W; z- I! M) S6 o }, ?) F5 t! n" k8 d
else5 G" ^4 q+ b B! d8 w- L/ ^
return 0;. J/ I& G6 j# A4 H7 ~
}7 l$ b" X; W* _( D6 `8 y) U- _
void time0_irq() interrupt 1 using 1 //系统时间定时器 10ms+1
0 T& n0 A) i4 r, w( N0 b{
! P7 r8 R. R9 `4 W0 Q9 o2 Z ~ TL0 = 0x00; //设置定时初值% f8 m% d- @2 G' E% E( _) f9 q
TH0 = 0xDC; //设置定时初值: |/ H" y% F* B; j2 Q2 T4 E" T# J
system_time++;; v5 t! g- y. Z
}4 s, |- D4 l1 O* N. r h$ E% Q
1 ?. ?2 y! \, U* f `) l, k2 k
. R0 \, g. F3 b; A9 d% ]
0 U/ G% C) I' F2 b/ B8 U: c& E说明:该工程使用了STC头文件,请在STC-ISP软件中将头文件添加到Keil
- ~, y; \2 k) }8 H0 N( T - }5 ]& m9 n, `/ E5 ~3 e( E
; z+ _) g3 f8 T5 d7 \( ~0 r
|
|