找回密码
 注册
关于网站域名变更的通知
查看: 177|回复: 2
打印 上一主题 下一主题

单片机教程25单片机键盘接口程序设计

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2022-8-11 10:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
   键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据。一般单片机系统中采和非编码键盘,非编码键盘是由软件来识别键盘上的闭合键,它具有结构简单,使用灵活等特点,因此被广泛应用于单片机系统。按钮开关的抖动问题2 @% m, G( V5 q. b1 B, f% ~  N% k
组成键盘的按钮有触点式和非触点式两种,单片机中应用的一般是由机械触点组成的。在下图中,当开
) b. E; y5 H  [7 u# H3 X* v<键盘结构图>
) t* L& ]5 |' I: O' ?

8 D4 \: l5 g3 _4 P1 Y$ @4 e& k! b8 N- Z            图1) M" F/ U! s4 F
; Y3 F$ O4 g! Z# ]7 h. g
            图2; U6 z6 E3 ~. V- }$ r
关S未被按下时,P1。0输入为高电平,S闭合后,P1。0输入为低电平。由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。0输入端的波形如图2所示。这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个“漫长”的时间了。前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。
) ^. F$ w; Z- v8 ~  @" t5 S为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除抖动,常用的去抖动的办法有两种:硬件办法和软件办法。单片机中常用软件法,因此,对于硬件办法我们不介绍。软件法其实很简单,就是在单片机获得P1。0口为低的信息后,不是立即认定S1已被按下,而是延时10毫秒或更长一些时间后再次检测P1。0口,如果仍为低,说明S1的确按下了,这实际上是避开了按钮按下时的抖动时间。而在检测到按钮释放后(P1。0为高)再延时5-10个毫秒,消除后沿的抖动,然后再对键值处理。不过一般情况下,我们常常不对按钮释放的后沿进行处理,实践证明,也能满足一定的要求。当然,实际应用中,对按钮的要求也是千差万别,要根据不一样的需要来编制处理程序,但以上是消除键抖动的原则。
) f) e# [) \4 ^0 l) _9 S键盘与单片机的连接6 j3 i: I/ X9 Q. C8 U. k

+ B  q% E/ z5 d( D# f# Z% t            <键盘连接>' x) Q- I) d& S$ b
            图3/ k; l' K9 X% K  e9 I! W/ ?
7 C  x  Q) @+ b+ ?; m' K
            <单片机与键盘接口图>
$ V4 ?) J2 ^% _! j- g; R            图4
7 s: x) y* B7 ?3 f4 L9 T. V
1、通过1/0口连接。将每个按钮的一端接到单片机的I/O口,另一端接地,这是最简单的办法,如图3所示是实验板上按钮的接法,四个按钮分别接到P3.2 、P3.3、P3.4和P3.5。对于这种键各程序能采用持续查询的办法,功能就是:检测是否有键闭合,如有键闭合,则去除键抖动,判断键号并转入对应的键处理。下面给出一个例程。其功能很简单,四个键定义如下:- B7 l% i0 P5 @7 U+ B. f! ]$ r
P3.2:开始,按此键则灯开始流动(由上而下), Y. [* C  h( q# G; f2 n
P3.3:停止,按此键则停止流动,所有灯为暗
5 S! v# j/ {' \8 Y7 fP3.4:上,按此键则灯由上向下流动
0 ]$ r* L, E4 u' y" OP3.5:下,按此键则灯由下向上流动' D1 z4 G. l3 P5 k  D: Z  v
UpDown EQU 00H ;上下行标志
4 d7 f8 g4 ?7 Q4 |9 H$ s# E2 @StartEnd EQU 01H ;起动及停止标志
- V& }1 G; G- p7 kLAMPCODE EQU 21H ;存放流动的数据代码+ S: \. J; P' A2 t$ y- O8 E7 d" a
ORG 0000H, ^' h" \, {+ }0 B1 x9 p2 p  z
AJMP MAIN# s% p; ?+ e. O6 |
ORG 30H
% B, E* ^4 F% T! i7 @' ?" eMAIN:
9 k% U9 z& g# J9 z& z8 G7 YMOV SP,#5FH& y  @8 i7 X+ j5 P, @) V. ^
MOV P1,#0FFH1 H/ E& K, X* a, n$ \1 \, L1 G9 }
CLR UpDown ;启动时处于向上的状态
$ b1 g" O8 P# r% s9 {9 L* V2 kCLR StartEnd ;启动时处于停止状态
: i; k6 M: E9 RMOV LAMPCODE,#0FEH ;单灯流动的代码- u" h2 ?5 M6 s: V* A: A5 ]
LOOP:
  I* [9 ?6 i# g9 GACALL KEY ;调用键盘程序% c6 O4 d6 e$ J2 @5 p
JNB F0,LNEXT ;如果无键按下,则继续
( O$ ~; n4 A/ v. ~6 I0 O1 Y  oACALL KEYPROC ;不然调用键盘处理程序
8 u% B9 ^; J6 Q+ F6 u' ?LNEXT:1 D, F2 v) J. m2 v4 {. B$ h0 c  ?
ACALL LAMP ;调用灯显示程序
% S' A1 l5 I$ s- s2 _5 i$ wAJMP LOOP ;反复循环,主程序到此结束$ Q9 T" C! w( ^3 \
DELAY:
+ s- ~# s  |5 z, H5 WMOV R7,#100
, L4 {6 T4 S! F  x3 c1 y6 N  `1 [D1: MOV R6,#100
8 d6 P) R: @3 @  B; TDJNZ R6,$0 S3 U3 N# x2 y. j3 J/ z5 V' ^
DJNZ R7,D1
# `  |4 B( `# L! I( r) gRET7 Y% m# d0 V' N/ S8 C4 P/ {8 y
;----------------------------------------延时程序,键盘处理中调用
% o1 u( [4 Y& }$ P  d  M) H1 s9 w- mKEYPROC:. N4 i. j6 N3 {
MOV A,B ;从B寄存器中获取键值/ x- ^6 s% x' r$ b6 s: N
JB ACC.2,KeyStart ;分析键的代码,某位被按下,则该位为1(因为在键盘程序中已取反)
* w% Z" H4 y9 C- R9 q% X" J% Q5 zJB ACC.3,KeyOver
8 V. v9 z# G/ N9 \3 J4 n; Z' ?JB ACC.4,KeyUp# E7 }  S8 E; G; f; J3 P) q
JB ACC.5,KeyDown# }" x6 h# X5 k. q( i! q* T
AJMP KEY_RET  w# r: c: n7 I1 F: X9 |3 |9 w
KeyStart:
" b, r$ a3 h+ z  zSETB StartEnd ;第一个键按下后的处理
2 e5 S  @5 P& ?3 ^$ r( x$ H! KAJMP KEY_RET
7 N% e" r4 E* [& C& eKeyOver:8 v4 [% U% b5 p$ U% R
CLR StartEnd ;第二个键按下后的处理2 `& Q+ @8 p- @4 A' w. N
AJMP KEY_RET
$ Z7 N# _' p' S- U" }0 G+ r% l5 TKeyUp: SETB UpDown ;第三个键按下后的处理, H3 ?9 B( X! ^) b5 ^8 q
AJMP KEY_RET
+ J1 {1 d7 n# z+ u# G  m4 {KeyDown:
8 d6 J. E$ n0 q! S( R. Q3 E1 aCLR UpDown ;第四个键按下后的处理. e6 \/ m# R4 y; R* v: ^
KEY_RET:RET
) m1 O; G: R1 u( P' q) _KEY:
: \6 d* H' ~5 P1 E+ _: T. ]0 s3 YCLR F0 ;清F0,表示无键按下。, P1 o; f2 k+ X* _
ORL P3,#00111100B ;将P3口的接有键的四位置1
/ A2 y* [, q5 E6 D0 ~MOV A,P3 ;取P3的值
) x8 M9 Y  _5 c  PORL A,#11000011B ;将其余4位置1
6 m. `5 |3 g  d, U4 ~4 q; q' ~* bCPL A ;取反, y7 m: x* f$ _6 H, U  G
JZ K_RET ;如果为0则一定无键按下
) L  I/ {" O" [9 k0 O; M4 h! C) KACALL DELAY ;不然延时去键抖
8 o" Z2 }' l# P" K! W0 \; M: RORL P3,#00111100B
5 ^* \: `; A, Z, ^/ u9 j) c; DMOV A,P32 `! ?: c) j. {6 M, t
ORL A,#11000011B
: m$ w" n1 ^$ ^1 Y5 pCPL A" D& e3 E2 V0 |& O$ d6 G
JZ K_RET$ u  d# z, R  ]# r7 H4 D
MOV B,A ;确实有键按下,将键值存入B中) X5 q; z' G7 K
SETB F0 ;设置有键按下的标志
) t% S; a6 V/ e7 S; c0 }; D  YK_RET:+ K4 }  K" P: I; X( k7 ^# }) I
ORL P3,#00111100B ;此处循环等待键的释放
( Y  Y: N# N0 f7 s- DMOV A,P3
, }( I- y5 a, J5 F6 JORL A,#11000011B, x# |' H/ ^6 `$ E1 v- \
CPL A
# H! O  L& {6 L+ QJZ K_RET1 ;直到读取的数据取反后为0说明键释放了,才从键盘处理程序中返回% Q1 w) l) f/ @) l7 Z* r5 ]
AJMP K_RET
' t1 S: `) M3 gK_RET1:# N; _/ g, n; ^6 T3 W3 f" I
RET
: A4 O0 Y$ o+ B" VD500MS: ;流水灯的延迟时间/ ?' F. U$ u& s& k
PUSH PSW0 F, D# e1 }% I7 D8 R; G
SETB RS0
. [: p$ ^. F9 ?* SMOV R7,#200
% s7 P6 C. a; LD51: MOV R6,#2503 I% r- Z( o: T
D52: NOP" r5 ^5 [% f% S) T3 k. _. a
NOP1 O& [& _6 p/ K' Q0 c+ s8 _6 D
NOP
4 t/ J+ Y% g  N& PNOP7 [5 ?8 l1 p# {, P; i) \3 g0 Y& t
DJNZ R6,D52
* K" W( N4 ~- _! A, ]4 nDJNZ R7,D51% y% ~- Y5 K: d4 C* c' Z- _, l
POP PSW
3 P1 U* J) M6 F& xRET
1 I/ |& K! v+ I, G! wLAMP:8 ?$ ^* d" G) {" s9 ?# z5 x: D
JB StartEnd,LampStart ;如果StartEnd=1,则启动
' A6 }3 t7 W4 M/ B% s1 gMOV P1,#0FFH' K+ ~9 e* t2 q9 o% A
AJMP LAMPRET ;不然关闭所有显示,返回
, v6 q/ Y6 u6 r6 V- OLampStart:
6 b3 `6 y. o9 d8 ?: e+ D+ fJB UpDown,LAMPUP ;如果UpDown=1,则向上流动
) r( v( b  V3 JMOV A,LAMPCODE! W1 I6 R$ S! u
RL A ;实际就是左移位而已) D' i9 I9 ^( t5 |+ _! _9 A
MOV LAMPCODE,A- B* x6 u2 ^* |' |
MOV P1,A
$ ?9 S) P% g/ G  y$ j2 ~3 i7 W. T0 XLCALL D500MS* C0 e, p4 l* V, i4 F0 S
AJMP LAMPRET' M, o8 i3 x& z7 E/ x8 ?
LAMPUP:
1 w" I; |) Z1 zMOV A,LAMPCODE
+ s! ]0 K- P. G" z# xRR A ;向下流动实际就是右移
3 N& B1 ?/ X) ~8 Z; pMOV LAMPCODE,A) {2 c% H  p$ m- @8 {* j% P5 U
MOV P1,A
; B. C6 A( `4 O$ V" J7 S" @LCALL D500MS5 S4 k6 u2 V: k% F. N# J
LAMPRET:- R2 C: x6 C( B- w
RET
4 A; H# ~! I4 x( v1 c. p8 ?3 _END$ G9 v# K( _, i) |  Y2 I
以上程序功能很简单,但它演示了一个单片机键盘处理程序的基本思路,程序本身很简单,也不很实用,实际工作中还会有好多要考虑的因素,比如主循环每次都调用灯的循环程序,会造成按钮反应“迟钝”,而如果一直按着键不放,则灯不会再流动,一直要到松开手为止,等等,大家能仔细考虑一下这些问题,再想想有什么好的解决办法。
5 G4 Q9 K5 C+ e( M  _2、采用中断方式:如图4所示。各个按钮都接到一个与非上,当有任何一个按钮按下时,都会使与门输出为低电平,从而引起单片机的中断,它的好处是不用在主程序中持续地循环查询,如果有键按下,单片机再去做对应的处理
. @5 X3 K4 S5 n7 y, C

该用户从未签到

2#
发表于 2022-8-11 11:25 | 只看该作者
谢谢楼主,很不错的东西

该用户从未签到

3#
发表于 2022-8-11 14:21 | 只看该作者
谢谢,看到了很不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-9-11 04:35 , Processed in 0.140625 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表