switch(readkey)
{
case 0x11:key=0; break;
case 0x21:key=1; break;
case 0x41:key=2; break;
case 0x81:key=3; break;
case 0x12:key=4; break;
case 0x22:key=5; break;
case 0x42:key=6; break;
case 0x82:key=7; break;
case 0x14:key=8; break;
case 0x24:key=9; break;
case 0x44:key=10;break;
case 0x84:key=11;break;
case 0x18:key=12;break;
case 0x28:key=13;break;
case 0x48:key=14;break;
case 0x88:key=15;break;
default: key=16;break;
}
keyout:_nop_();
}
ADDR_KEY EQU 8040H ;键盘片选地址
KEY_TMP EQU 70H ;键值暂存单元
;********************************************
;键盘数码显示器测试程序
LEDDATA EQU P1.0 ;数码管显示 74LS164 的数据线
LEDCLK EQU P1.1 ;数码管显示 74LS164 的时钟线
LEDBUF1 EQU 30H ;显示缓冲区,对应数码管L4
LEDBUF2 EQU 31H ;显示缓冲区,对应数码管L3
LEDBUF3 EQU 32H ;显示缓冲区,对应数码管L2
LEDBUF4 EQU 33H ;显示缓冲区,对应数码管L1
;主程序***************************************************
ORG 0000H
LJMP MAIN
ORG 0030H
MAIN: LCALL CLEARDISP ;清除显示器上的显示内容
start: LCALL KEY
CJNE A,#0FFH,DISPA
SJMP start
DISPA: MOV LEDBUF1 , A ;显示"A中键代码"
MOV LEDBUF2 , #12H
MOV LEDBUF3 , #12H
MOV LEDBUF4 , #12H
LCALL DISPNUMBER ;调用显示程序
AJMP start
;子程序**************************************************
;清除显示器显示的内容
CLEARDISP:
MOV R0,#04H
CLEARDISP_0:
MOV A, #0FFH
LCALL SENDDATA
DJNZ R0,CLEARDISP_0
RET
;**********************************************************
;发送数据 :发送的数据在ACC中
SENDDATA:
PUSH 01H
CPL A
MOV R1 ,#08H
SENDDATA_0:
CLR C
RRC A
MOV LEDDATA, C ;移位发送
CLR LEDCLK
SETB LEDCLK
DJNZ R1,SENDDATA_0
POP 01H
RET
;键盘行扫描程序*********************************************
; (1) 功能:有键闭合,键值存在A中,否则A中存入无键闭合
;标志FFH
; (2) 入口参数:无;出口参数:Acc;
;使用寄存器:R2-R7, KEY_TMP, A, DPTR
KEY: LCALL KS1 ;检查是否有闭合键
JNZ LK1 ;有键合
LJMP MK8 ;无
LK1: LCALL DL10MS ;消抖动
LCALL DL10MS
LCALL KS1
JNZ LK2
LJMP MK8
LK2: MOV R3, #00H ;列计数器初值00H送R3
MOV R2, #0F7H ;列扫描初值送R2
LK3: MOV A, R2
MOV DPTR, #ADDR_KEY
MOVX @DPTR, A
MOVX A, @DPTR
ANL A, #0F0H
CJNE A, #0F0H, LK4
INC R3 ;列计数器加1
MOV A, R2 ;修改列码
JNB ACC.0, MK8 ;列扫描完成否?
RR A
MOV R2, A
SJMP LK3
LK4: JB ACC.7, LK5
MOV A, #00H
ADD A, R3
SJMP LK9
LK5: JB ACC.6, LK6
MOV A, #04H
ADD A, R3
SJMP LK9
LK6: JB ACC.5, LK7
MOV A, #08H
ADD A, R3
SJMP LK9
LK7: JB ACC.4, MK8
MOV A, #0CH
ADD A, R3
SJMP LK9
LK9: MOV KEY_TMP, A ;暂存键值
LK10: LCALL KS1
JZ LK11
LCALL DL10MS ;调用延时
SJMP LK10
LK11: MOV A, KEY_TMP
SJMP LK12
MK8: MOV A, #0FFH
LK12: RET
KS1: MOV DPTR,#ADDR_KEY ;键盘接口地址
MOV A,#0F0H ;D3~D0送0000
MOVX @DPTR,A ;列全0送出
MOVX A,@DPTR ;读行信息
ANL A,#0F0H ;屏蔽低4位
ORL A,#0FH ; 底4位置1
CPL A ;产生A=0为无键按下特征
RET
;**********************************************************
;显示缓冲区的数字
DISPNUMBER: MOV R0, #LEDBUF1
MOV R1, #04H
DISPNUMBER_0: MOV A, @R0
MOV DPTR, #TABLE
MOVC A, @A+DPTR ;得到数字的字型码
LCALL SENDDATA
INC R0
DJNZ R1 , DISPNUMBER_0
RET
;***************************************************
;延时程序
DL10MS: MOV R5, #100
DELAY1: MOV R6, #100
DJNZ R6, $
DJNZ R5, DELAY1
RET
;**********************************************************
;串行显示码格式:|e |d |c |dp |b |a |f |g
; 7 6 5 4 3 2 1 0
TABLE: DB 011H ;0的显示码
DB 0D7H ;1的显示码
DB 032H ;2的显示码
DB 092H ;3的显示码
DB 0D4H ;4的显示码
DB 098H ;5的显示码
DB 018H ;6的显示码
DB 0D3H ;7的显示码
DB 010H ;8的显示码
DB 090H ;9的显示码
DB 050H ;A的显示码
DB 01CH ;B的显示码
DB 039H ;C的显示码
DB 016H ;D的显示码
DB 038H ;E的显示码
DB 078H ;F的显示码
DB 0FEH ;-的显示码
DB 070H ;P的显示码
DB 0FFH ;全熄的显示码
END