EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
在单片机系统里,按键是常见的输入设备,在本文将介绍几种按键硬件、软件设计方面的技巧。一般的在按键的设计上,一般有四种方案。8 ?+ f& g- B8 g0 K. r0 l9 \7 V
7 d6 M, ~' H3 u. I
" v; i5 d; h$ H! d1 q% L* O一是 GPIO 口直接检测单个按键,如图 1.1 所示;4 {0 d. a W: s
( d$ |( \9 m7 V* _7 r5 ?二是按键较多则使用矩阵键盘,如图 1.2 所示;
5 ^+ W; ?2 W! k8 p: b( C5 W
8 E- j8 i: I5 j- y& K: C三是将按键接到外部中断引脚上,利用按键按下产生的边沿信号进行按键检测,如图 1.3 所示;
" h7 t' o: m5 F$ ~7 n5 g5 A, J2 Q6 u+ ^; e. j5 g! e# }9 A& F
四是利用单片机的 ADC,在不同的按键按下后,能够使得 ADC 接口上的电压不同,根据电压的不同,则可以识别按键,如图 1.4 所示。
# H. u* r3 K/ M# A) x) g: M* ~
7 ^; C: g2 t- V# ~* ^# @, q. k' k Y; A" k9 J/ U
图 1.1 方案一7 V9 f2 d& N7 h2 M4 }( `2 s j
3 Q2 d7 z1 }% \ n& L4 q, h9 J7 T: w$ l! h* \/ w* F: W+ P
图 1.2 方案二
. b: B9 @; s/ v) s0 ]
. \% ~; Q- k9 H# v( p8 X
& c8 G: [0 u L. c& b9 g( a图 1.3 方案三) h5 ~6 m4 [, V2 s4 S* Z
0 K x6 `% T7 d( L& t$ R* H3 _4 ]: c7 Z* f" u
图 1.4 方案四" k+ A. ^, B" V! u1 [3 ^, @
! o$ U" y6 @* `* L1 t' W3 o
在以上四种设计上,各有优点和不足。
4 ^5 u! e' x# _1 ]! a0 l; s% p
/ @: |6 v$ L6 g% O; Z7 q第一种,是最简单和最基础的,对于单片机初学者很容易理解和使用,但是缺点是,需要在主循环中不断检测按键是否按下,并且需要做消抖处理。若主循环中某个函数任务占用时间较长,则按键会有不同程度的“失灵”。
9 _+ q* B, J, L
% c, k8 V. j( t第二种,优点是能够在有限的 GPIO 情况下,扩展尽可能多的按键。但缺点同上,需要不停检测按键是否按下。7 p; c; J3 F: p: h3 d
, e2 s! [4 Z8 R8 @第三种,是效率最高,不需要循环检测按键是否按下,但是缺点是,需要单片机有足够的外部中断接口以供使用。
3 p5 S- e7 d# v7 I3 C
6 v$ ~% n' k: y7 i2 r第四种,优点是,只需要单片机的一个 ADC 接口,一根线,就能对多个按键进行识别,缺点是按键一旦内部接触不良,则可能按键串位,且按键产生的抖动,会造成一定的识别错误。
9 g" o2 h7 H1 m; s
. ~+ C2 V$ j) o( f在以上的三种常见按键设计的基础上,现在分享我学习和工作中总结的按键方案。
% ^6 V- o! m0 b' O9 z7 _& V1 I* |8 i: y u
改进一:在原方案一的基础上,加上与门电路,使得任何一个按键按下,都能产生中断,然后在中断里面识别是哪个按键被按下。因此不需要循环扫描,大大提高了效率。方案如图 1.5 所示。只需要每个按键对应地增加一个二极管,利用二极管的线与特性,可以实现按下任何按键,都能产生中断信号,但是按键之间互不影响。二极管选用普通整流二极管即可,本人亲测可行。
4 s) g& R' J: u9 y- F) Z
7 M- \1 o o) {6 B+ m: ^4 V( {# h5 i& O* C. |
图 1.5 改进一. f+ z3 ^7 c( o+ U1 L
/ T# l, _* m6 \ c/ o4 g
改进二:在原有的 ADC 按键的基础上,也可用增加二极管的方式,实现按键中断,并在中断服务程序里进行 AD 转换,从而识别按键。电路如图 1.6 所示。
* s0 ]/ t3 ~) k% N4 C7 X+ P( h7 u/ [" m) c7 X* W
3 w3 J. y. p4 B
图 1.6 改进二$ s* a/ i; U$ } ^
1 M' T; h4 P# ~改进三:因为按键不可避免的有抖动,因此按键消抖可以通过硬件消痘和软件消抖。现在分享一个十分简单且有效的硬件消痘方法:给按键并联一个 104 左右的电容。软件上基本不用处理即可避免抖动。& k$ y6 Y* M/ E" B& A4 t$ n3 U) Z3 U
. e0 I' v& ?( C+ Q% O4 _6 W
改进四:在按键扫描检测的方案下,如果主循环中有某个函数占用时间较长,则按键会发生或长或短的“失灵”,现分享我的一个解决方案。将按键扫描放到定时器中断里面,这样就可周期性地检测按键按下情况,不受主循环的影响。
5 j; z q! `* v& t- r
1 K1 L8 a' t7 p) h4 o# {并且,能解析出按键的不同状态,即按下、按住、弹起、为按下这四种状态,用以实现更丰富的功能。
! Y4 e7 A: f# g& b g% o0 G' V/ G: g' B+ _) |: s# n
但需注意两点:一是定时器的定时时间,不可过长也不可过短,过长容易检测不到按下,过短会占用大量时间资源。二是中断服务程序需简单明了,只做检测用,通过全局变量传递,在主循环内完成按键响应,中断服务函数内尽量不要占用太多时间。2 h- A) X1 J# o% ?0 P7 j, X+ J
|