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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
   键盘是由若干按钮组成的开关矩阵,它是单片机系统中最常用的输入设备,用户能通过键盘向计算机输入指令、地址和数据。一般单片机系统中采和非编码键盘,非编码键盘是由软件来识别键盘上的闭合键,它具有结构简单,使用灵活等特点,因此被广泛应用于单片机系统。按钮开关的抖动问题( L9 Y" X' J6 ?0 f! X( @$ j# F
组成键盘的按钮有触点式和非触点式两种,单片机中应用的一般是由机械触点组成的。在下图中,当开
( y" k: q2 D4 g2 Z! y( h# a<键盘结构图>5 k* ^; I$ W6 I. q0 p/ t& y0 Z* W& n+ ^

/ g# c  \. }% G7 _            图1
9 }0 }! k& |$ S# i2 e
/ R0 k: j6 _; U  A7 F: d9 @
            图2
6 E! x& B: V; Z. ]+ F
关S未被按下时,P1。0输入为高电平,S闭合后,P1。0输入为低电平。由于按钮是机械触点,当机械触点断开、闭合时,会有抖动动,P1。0输入端的波形如图2所示。这种抖动对于人来说是感觉不到的,但对计算机来说,则是完全能感应到的,因为计算机处理的速度是在微秒级,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个“漫长”的时间了。前面我们讲到中断时曾有个问题,就是说按钮有时灵,有时不灵,其实就是这个原因,你只按了一次按钮,可是计算机却已执行了多次中断的过程,如果执行的次数正好是奇数次,那么结果正如你所料,如果执行的次数是偶数次,那就不对了。3 R6 e( w, H4 T' [8 \8 p
为使CPU能正确地读出P1口的状态,对每一次按钮只作一次响应,就必须考虑如何去除抖动,常用的去抖动的办法有两种:硬件办法和软件办法。单片机中常用软件法,因此,对于硬件办法我们不介绍。软件法其实很简单,就是在单片机获得P1。0口为低的信息后,不是立即认定S1已被按下,而是延时10毫秒或更长一些时间后再次检测P1。0口,如果仍为低,说明S1的确按下了,这实际上是避开了按钮按下时的抖动时间。而在检测到按钮释放后(P1。0为高)再延时5-10个毫秒,消除后沿的抖动,然后再对键值处理。不过一般情况下,我们常常不对按钮释放的后沿进行处理,实践证明,也能满足一定的要求。当然,实际应用中,对按钮的要求也是千差万别,要根据不一样的需要来编制处理程序,但以上是消除键抖动的原则。, _3 i  I. a8 H0 m! V* x
键盘与单片机的连接3 `: i  v/ N8 F8 D" Q3 k. m$ w
' e( s9 O$ R( o9 C0 e5 k- m5 P
            <键盘连接>: H$ L. M3 d/ F9 k1 R1 g  ]
            图38 D/ J' {, i1 I# `" ^0 [

5 P1 _0 j: Q9 J, F  |5 G- s            <单片机与键盘接口图>
# z$ n* @3 s! n4 a. |" k7 u            图4
' f  p$ h9 P2 A6 e
1、通过1/0口连接。将每个按钮的一端接到单片机的I/O口,另一端接地,这是最简单的办法,如图3所示是实验板上按钮的接法,四个按钮分别接到P3.2 、P3.3、P3.4和P3.5。对于这种键各程序能采用持续查询的办法,功能就是:检测是否有键闭合,如有键闭合,则去除键抖动,判断键号并转入对应的键处理。下面给出一个例程。其功能很简单,四个键定义如下:* j; ^- k$ `! J2 p5 L* e
P3.2:开始,按此键则灯开始流动(由上而下)
) ]& j. Y4 Z0 e! N& z; [P3.3:停止,按此键则停止流动,所有灯为暗8 _. V) p' B$ u
P3.4:上,按此键则灯由上向下流动
% Z% c3 g6 `8 W) `' J, J. c0 BP3.5:下,按此键则灯由下向上流动; a  P$ m3 e4 q# ~' \# f' X
UpDown EQU 00H ;上下行标志9 w7 K3 A9 n( s- v# @& t
StartEnd EQU 01H ;起动及停止标志
! e' A3 \2 z. b5 o0 O; vLAMPCODE EQU 21H ;存放流动的数据代码
' ?8 ~' W7 w% R& |ORG 0000H
% S. o: [% J* E7 {AJMP MAIN
9 D3 u9 g2 l9 q  SORG 30H! |- l0 u4 o1 F
MAIN:- [5 P+ {( Q* U# i% F8 }# {$ }
MOV SP,#5FH
* f' A- q" n* j9 W/ jMOV P1,#0FFH3 p2 V- B4 {/ I
CLR UpDown ;启动时处于向上的状态1 F. O, d/ K; U/ N9 j
CLR StartEnd ;启动时处于停止状态
7 m2 ^8 S8 R( P5 S, W" J$ [, ^MOV LAMPCODE,#0FEH ;单灯流动的代码
3 t8 n# i+ q$ y& jLOOP:
! n9 `1 B9 N& h& [. X# r* aACALL KEY ;调用键盘程序
. y! l/ P9 K1 ^. ]  I$ [, sJNB F0,LNEXT ;如果无键按下,则继续
+ h* J7 B* Q/ ~$ J7 lACALL KEYPROC ;不然调用键盘处理程序
" F: Y6 C2 J6 W5 L& n8 m# B7 PLNEXT:
6 E& H/ s3 `3 F# yACALL LAMP ;调用灯显示程序
- o1 w$ ]/ y, k% N7 x; v* YAJMP LOOP ;反复循环,主程序到此结束$ t% j& F/ E- E$ s( M' w
DELAY:
  R- o  Q1 [9 i7 HMOV R7,#100! m0 T: A/ C4 V4 d' i
D1: MOV R6,#100
+ m* u4 P# f, |DJNZ R6,$
6 F" P: B' s% d/ C5 K9 J' R8 i/ p0 NDJNZ R7,D1
$ _  E' D- o  i. \* CRET
' N, W" {9 F; ]0 ?;----------------------------------------延时程序,键盘处理中调用+ v3 x3 N9 H& n8 f9 |2 u( |
KEYPROC:3 s: t, P! L4 G1 @4 g" `+ Z+ V
MOV A,B ;从B寄存器中获取键值. Z2 M7 J+ H0 e6 ?
JB ACC.2,KeyStart ;分析键的代码,某位被按下,则该位为1(因为在键盘程序中已取反)
4 n4 Z5 D/ B! h7 u& cJB ACC.3,KeyOver
- i" v! ]% e0 NJB ACC.4,KeyUp
4 \  z; G# i+ f7 \5 W: b' eJB ACC.5,KeyDown
' f6 d# {6 o* M0 ^$ R" Y5 gAJMP KEY_RET1 c; @3 s- T9 x5 |1 ^, `- }: ?
KeyStart:
) n( v0 r0 h, OSETB StartEnd ;第一个键按下后的处理8 H% w1 |; Z+ P9 d2 ^1 I" b
AJMP KEY_RET: ^! H6 }7 ?8 d2 N0 Y9 k
KeyOver:% r2 L. i! w  K7 N) c+ A
CLR StartEnd ;第二个键按下后的处理
% p5 _* G9 w8 V0 F5 \9 O- \AJMP KEY_RET. h) b8 E! x3 a
KeyUp: SETB UpDown ;第三个键按下后的处理
9 w8 w& L" x! P  ]( `AJMP KEY_RET, [1 |' I( G  J5 f! {' _. r
KeyDown:8 o# b" k; n6 N( o0 M
CLR UpDown ;第四个键按下后的处理
2 A& e4 s: j& e& h; k4 s5 Y5 WKEY_RET:RET
* R, R8 D' t( Z3 [# QKEY:" A9 o+ _# R$ ]0 O+ j
CLR F0 ;清F0,表示无键按下。8 o2 e, j9 v8 k
ORL P3,#00111100B ;将P3口的接有键的四位置1
2 `* L1 x4 f# Q2 bMOV A,P3 ;取P3的值
$ W2 o: |) p1 XORL A,#11000011B ;将其余4位置1
5 M: A+ V8 s% g; FCPL A ;取反  `7 m7 }: F0 j) O+ e, t5 P
JZ K_RET ;如果为0则一定无键按下+ N  x8 v7 }" P
ACALL DELAY ;不然延时去键抖
7 E; o3 s5 j  o1 MORL P3,#00111100B
7 u/ h1 x2 M* Y; r+ kMOV A,P3
8 l3 W9 I( q2 L3 }$ C) SORL A,#11000011B  ]! P! v0 F$ v3 p! j5 g9 b9 T
CPL A
' P# r9 W  T0 U: p0 a0 K7 R% T5 MJZ K_RET
6 @" q4 w2 n, ~5 e  T( vMOV B,A ;确实有键按下,将键值存入B中3 L0 C# T8 {5 u! F
SETB F0 ;设置有键按下的标志
8 p- t  O; \$ `0 s* cK_RET:
- B/ N/ S' J& O1 VORL P3,#00111100B ;此处循环等待键的释放
/ T* S" x4 a4 C; J9 r! t! u; PMOV A,P3* K, K! ^( a# b' o5 ^4 N5 K; M
ORL A,#11000011B
9 G6 h  d1 ~0 ]7 n- k' iCPL A, P! F" `9 u2 i- [2 S. @1 s6 H( R- T, R4 P
JZ K_RET1 ;直到读取的数据取反后为0说明键释放了,才从键盘处理程序中返回* c3 z$ y3 s: r$ ?
AJMP K_RET6 o  K) i( G% C/ y' y
K_RET1:
% f) S: f: ]* |% B0 u9 ERET
" ^& [, V- K3 w: v) \D500MS: ;流水灯的延迟时间2 M+ y+ s- ]" w1 H+ {* A& P, W
PUSH PSW
- `7 a, Z: {, P! p8 sSETB RS0- q3 S% A6 B; {) H4 [: X) c
MOV R7,#2004 {3 m5 C+ ?) b% J, }( r
D51: MOV R6,#250
* I( G9 f5 q( r# [( G2 iD52: NOP
/ d0 w$ y+ o. O  hNOP3 M2 w/ C# I  E7 c  w! y; [# R
NOP
$ [% i; z& w% mNOP
3 P0 m# {4 c# L+ HDJNZ R6,D52
& k( {# }5 J! f$ H" G& P* tDJNZ R7,D51; r, b4 b0 y+ T, f2 ]# w0 w
POP PSW" z% t  Q/ ^" G' q" N
RET4 v! m6 L0 H) {" u
LAMP:
# v; j) l- V* v4 W  QJB StartEnd,LampStart ;如果StartEnd=1,则启动2 c: s! i( x) ~
MOV P1,#0FFH
, F/ W9 R4 j7 @; `2 E$ w) PAJMP LAMPRET ;不然关闭所有显示,返回
. }8 O; q  |6 m( l# [6 dLampStart:
1 Z) [( Y* f$ H7 XJB UpDown,LAMPUP ;如果UpDown=1,则向上流动3 P2 w3 k" r& m5 o  u2 J
MOV A,LAMPCODE- E7 O5 f5 ~2 c7 W% n) T$ v$ q
RL A ;实际就是左移位而已
+ {* z) H: t" z% o; uMOV LAMPCODE,A
6 H$ c4 M  f: f4 Q6 c0 A3 }MOV P1,A
( v% B( B2 R: \3 B3 _. c( BLCALL D500MS6 ?4 x' e. J+ g7 y1 ]1 X( p( b3 y
AJMP LAMPRET
; B4 `+ f$ Z4 bLAMPUP:9 N( {! H. F8 D/ @5 T2 f  o4 y4 p
MOV A,LAMPCODE) P. @+ s0 }! T1 k7 L6 `8 O* n6 q
RR A ;向下流动实际就是右移
& s9 G, Z3 k& {: T$ @MOV LAMPCODE,A
# L+ s8 I1 `6 t2 MMOV P1,A; L9 V5 r- q+ J( S$ t; o; D0 T8 A2 l
LCALL D500MS
; p$ ^2 i8 O/ y3 W: v- X) cLAMPRET:
! n( O$ {7 A. v' zRET
* h5 o/ U! E$ J5 B3 FEND
0 S/ R- {  u0 G, w  `  N6 Z以上程序功能很简单,但它演示了一个单片机键盘处理程序的基本思路,程序本身很简单,也不很实用,实际工作中还会有好多要考虑的因素,比如主循环每次都调用灯的循环程序,会造成按钮反应“迟钝”,而如果一直按着键不放,则灯不会再流动,一直要到松开手为止,等等,大家能仔细考虑一下这些问题,再想想有什么好的解决办法。
  ]. p2 R  t' p8 ?2、采用中断方式:如图4所示。各个按钮都接到一个与非上,当有任何一个按钮按下时,都会使与门输出为低电平,从而引起单片机的中断,它的好处是不用在主程序中持续地循环查询,如果有键按下,单片机再去做对应的处理
1 G, k$ w, L0 R. z6 G( u# _" r. O' |

该用户从未签到

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

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-8-23 23:30 , Processed in 0.109375 second(s), 23 queries , Gzip On.

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

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

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