在无键压下时,由于接到+5V上的上拉电阻的作用,列线被置成高电平。压下某一键后,该键所在的行线和列线接通。这时,如果向被压下键所在的行线上输出一个低电平信号,则对应的列线也呈现低电平。当从B口读取列线信号时,便能检测到该列线上的低电平。读取B口的状态时,还能读到行线上的低电平信号。这样,根据读入的行和列状态中低电平的位置,便能确定哪个键被压下了。
二、键盘与微机的接口及处理方式
1. 行扫描方式
识别键盘上哪个键被压下的过程称为键盘扫描,上述键盘的扫描包含以下几步: (1) 检测是否所有键都松开了,若没有则反复检测。
(2) 当所有键都松开了,再检测是否有键压下,若无键压下则反复检测。 (3) 若有键压下,要消除键抖动,确认有键压下。
(4) 对压下的键进行编码,将该键的行列信号转换成16进制码,由此确定哪个键被压下了。如出现多键重接的情况,只有在其它键均释放后,仅剩一个键闭合时,才把此键当作本次压下的键。
(5) 该键释放后,再回到(2)。
检测矩阵中是否有键压下的一种简单方法是,自输出口A向所有行线输出0电平,再通过B口的低4位读取列值,若其中有0值,便是有键压下了。
在开始一次扫描时,先应确认上一次压下的键是否已松开。即先向所有行线输出低电平,再读人各列线值,只有当所有的行线和列线均为高电平,表示以前压下的键部已释放了,才开始检测是否有键压下。
当检测到有键压下后,必须消除键抖动( Debance)。消除键抖动的常用方法是在检测到有键压下后,延长一定时间(通常为20ms),再检查该键是否仍被压着。若是,才认定该键确实被接下了,而不是干扰。
确认有键压下后,再确定被压下键所在的行列号。为获取行列信息,先从A口输出一个低电平到一行线上,再从B口读人各列的值,若没有一列为低电平,说明压下的键不在此行。于是,再向下一行输出一个低电平,再检测各列线上是否有低电平。依次对每一行重复这个过程,直至查到某一列线上出现低电平为止。被置成低电平的行和读到低电平的列,便是被压下键所在的行列值。
已知被压下的键所在的行号(0~3)和列号门~3)后,就能得到该键的扫描码。例如,对于数字0,它位于3行、3列,压下“0”键时,从B口可读得D7位和D3位为0,其余位为1,所以数字0的编码为01110111B,即77H;对于数字6,处于2行1列,压下‘6’键时,D6位和D1位0以其余位为1,所以数字6的编码为10111101B=BDH。类似地,其余各键的编码也可—一求得。将这些编码值列成表,放在数据段中,用查表程序来查对,便能确定压下的是什么键。
17
2. 程序实现
下面是键盘检测、去抖动、键值编码和确定键名的汇编语言程序。程序运行后,若返回值AH=0,表示已读到有效的键值,并在AL中存有0~F键的16进制代码;若AH=l,则表示出错。
;端口地址
PORT-A EQU 0FF9H;8255 A口地址 PORT-B EQU 0FFBH;8255 B口地址 PORT-CTL EQU 0FFFH;8255控制口地址 ;数据段,键盘扫描码表 DATA SEGMENT
;0 1 2 3 4 5 6 7
TABLE DB 77H, 7BH, 7DH, 7EH, 0B7H,0BBH,0BDH,0BEH
; 8 9 A B C D E F DB 0D7H,0DBH,0DDH,0DEH,0E7H,0EBH,0EDH,0EEH
DATA ENDS ;堆栈段
STACK SEGMENT STACK
DW 50DUP(0) TOP_STACI LABEL WORD STACK ENDS ;代码段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK START:MOV AX, STACK
MOV SS, AX LEA SP, TOP_STACK MOV AX, DATA MOV DS, AX
;初始化8255A,方式0,A口作输出,B口和C口为输人
MOV DX, PORT-CTL;指向控制口 MOV AL,10001011B;控制字 OUT DX, AL;写人控制字
;向所有行送0
MOV DX,PORT-A;A口 MOV AL,00H
18
OUT DX, AL;向 A口各位输出 0
;读列,查看是否所有键均松开
MOV DX,PORT-B
WAIT_OPEN IN AL,DX;键盘状态读人 B口
AND AL, 0FH;只查低4位(列值) CMP AL,0FH;是否都为1(各键均松开)? JNE WAIT_OPEN;否,继续查
;各键均已松开,再查列是否有0,即是否有键压下 WAIT_ PRES: IN AL,DX;读B口
AND AL,0FH;只查低4位 CMP AL,0FH;是否有键压下 JE WAIT_PRES;无,等待
;有键压下,延时20ms,消抖动
MOV CX, 16EAH
DELAY:LOOP DELAY;延时20ms ;再查列,看键是否仍被压着
IN AL,DX AND AL,0FH CMP AL,0FH
JE WAIT_PRES;已松开,转出等待压键
;键仍被压着,确定哪一个键被压下
MOV AL,0FEH;先使风一0 MOV CL,AL;CL=1111 1110B
NEXT_ROW:MOV DX,PORT-A; A口
OUT DX, AL;向一行输出低电平 MOV DX, PORT-B;B口 IN AL, DX;读人B口状态 AND AL,0FH;只截取列值 CMP AL,0FH;是否均为何
JNE ENCODE;否,表示有键压下,转去编码 ROL CL,01;均为1,使下行输出0 MOV AL, CL
JMP NEXT_ROW;查看下行
;已找到有一列为低电平,对压键的行列值编码
ENCODE:MOV BX , 000FH;建立地址指针,先指向F键对应的地址19
IN AL,DX;从B口读人行列号
NEXT.TRY:CMP AL,TABL可B川;读人的行列值与表中查得的相等吗?
JE DONE;相等,转出
DEC BX;不等,指向下一个(键值较小者)地址 JNS NEXT_TRY;若地址尚末减为负值,继续查 MOV AH,01;若减为负值,置出错码01—AH中 JMP EXIT;退出
DONE:MOV AL,BL; BL中存有键的 16进制代码
MOV AH, 00;AH=0,读到有效键值
EXIT:HLT CODE ENDS
END
9.4 显示器与键盘的接口
一、LED显示器的结构
二、LED显示器与微机的接口及处理方式
1.接口电路 2.多位动态显示 (实验)
20