LNUM EQU 0030H //將0030H定義為LNUM;
ORG 0000H //程序在儲存器中存放的起始位置;
JMP START //跳轉(zhuǎn)到START;
ORG 0100H //程序在儲存器中存放的起始位置;
START: MOV SP,#5FH //初始化SP值為5FH;
MOV LNUM,#4 //共4行;
MOV P2,#9FH //初始化數(shù)碼管顯示為1;
CLR F0 //清零F0,初始化;
ST1: CALL MAKEY //單元矩陣鍵盤掃描子程序;
JNB F0,ST1 //F0為0時無鍵按下,繼續(xù)掃描;
ANL A,#0FH //有鍵按下時,鍵號在A中;
MOV DPTR,#CODE_P2 //將CODE_P0定義的數(shù)據(jù)表的首地址送給DPTR;
MOVC A,@A+DPTR //查表;
MOV P2,A //顯示所有按鍵的鍵號;
JMP ST1 //跳轉(zhuǎn)到ST1;
MAKEY: CALL KEYHN //調(diào)用子程序KEYHN;
JNZ HAVE //有鍵按下;
JMP NRET //清零F0,并返回再次進行下面的程序;
HAVE: CALL D10ms //調(diào)用D10ms,延時10ms;
CALL KEYHN //延時后再判,去抖動;
JNZ TRUE //確認有按鍵按下;
JMP NRET //清零F0,并返回再次進行下面的程序;
TRUE: MOV R1,#0EFH //首列掃描字;
MOV R4,#0 //首列號;
SCAN: MOV A,R1 //將R1中的值送給給A;
MOV P1,A //將A中的值送給P1;
MOV A,P1 //將P1中的值送給A;
JB ACC.0,L1 //0行無鍵按下,轉(zhuǎn)1行;
MOV A,#0 //0行首鍵號;
JMP KEYNUM //轉(zhuǎn)鍵號計算;
L1: JB ACC.1,L2 //1行無鍵按下,轉(zhuǎn)2行;
MOV A,#4 //1行首鍵號;
JMP KEYNUM //轉(zhuǎn)鍵號計算;
L2: JB ACC.2,L3 //2行無鍵按下,轉(zhuǎn)3行;
MOV A,#8 //2行首鍵號;
JMP KEYNUM //轉(zhuǎn)鍵號計算;
L3: JB ACC.3,NEXT //3行無鍵按下,轉(zhuǎn)下一行;
MOV A,#0CH //3行首鍵號;
KEYNUM: ADD A,R4 //鍵號=行首號+列號;
PUSH ACC //將ACC中數(shù)給SP中;
UPKEY: CALL KEYHN //調(diào)用子程序KEYHN;
JNZ UPKEY //等待鍵釋放;
POP ACC //將SP中的數(shù)給SP中;
SETB F0 //置有鍵按下標志;
JMP HRET //跳轉(zhuǎn)到HRET;
NRET: CLR F0 //清零有鍵按下標志;
HRET: RET //返回到調(diào)用子程序NRET的下面;
NEXT: INC R4 //R4自加1,下一列;
MOV A,R1 //將A中的數(shù)送給R1;
DJNZ LNUM,NDONE //若LUNM減1不為0,則跳轉(zhuǎn)到NDONE;
//若LUNM減1為0,則程序往下執(zhí)行;
JMP NRET //跳轉(zhuǎn)到NRET;
NDONE: RL A //掃描字左移,準備掃描下一列;
MOV R1,A //置高四位全為0,低四位輸入狀態(tài);
JMP SCAN //跳轉(zhuǎn)到SCAN;
KEYHN: MOV P1,#0FH //置高四位全為0,低四位輸入狀態(tài);
MOV A,P1 //將0FH送給A;
CPL A //將A中的數(shù)取反再送給A;
ANL A,#0FH //A的高四位清零,低四位輸入狀態(tài);
RET //返回;
D10ms: MOV R5,#10 //10ms;
D1ms: MOV R4,#249 //
DL: NOP //空操作;
NOP //空操作;
DJNZ R4,DL //R4減1,若為0,則結(jié)束循環(huán),程序往下執(zhí)行;
//若不為0,則跳轉(zhuǎn)到DL;
DJNZ R5,D1ms //R5減1,若為0,則結(jié)束循環(huán),程序往下執(zhí)行;
//若不為0,則跳轉(zhuǎn)到D1ms;
RET //返回;
CODE_P2:DB 03H,9FH,25H,0DH,99H,49H,40H,1FH
DB 01H,09H,11H,0C1H,63H,85H,61H,71H //數(shù)碼管顯示數(shù)據(jù)表,0——F;
END //結(jié)束;
|