KEYCARD BIT 00H ;用於標誌是否有鍵按下
KEYS EQU 5AH ;記錄鍵值
KEY1 EQU 5BH ;記錄行掃描時的值
KEY2 EQU 5CH ;記錄列掃描時的值
ORG 0000H ;程序開始
AJMP START
ORG 30H ;爲避免佔用中斷向量區,主程序從30H開始
START:
MOV SP,#5FH ;設置堆棧的初始地址
MOV P3,#0FH ;P3,P2,P0的初始化
MOV P2,#00H
MOV P0,#0FFH
MOV KEYS,#00H ;各鍵值清0
MOV KEY1,#00H
MOV KEY2,#00H
CLR KEYCARD ;有按鍵標誌清0
LOOP: ;循環掃描鍵盤
ACALL KEY_CHECK
JNB KEYCARD,LOOP
ACALL KEY_VAL ;如果有鍵按下,則確定是哪一個鍵按下
AJMP LOOP
KEY_CHECK: ;看有沒有鍵按下
MOV A,P3
ANL A,#0FH
CJNE A,#0FH,KEY_CER ;如果讀入的與寫出的不相等,延時消抖
CLR KEYCARD
RET
KEY_CER: ;延時,再讀入,看是否真的有鍵按下
ACALL DELAY1S
MOV A,P3
ANL A,#0FH
CJNE A,#0FH,KEY_CE
CLR KEYCARD
RET
KEY_CE:
SETB KEYCARD ;真的有鍵按下,則置標誌位
RET
KEY_VAL: ;用於獲得鍵值碼
MOV P3,#0FH
MOV A,P3
MOV KEY1,A ;行鍵值碼
ANL A,#0FH
CJNE A,#0FH,KEY_M1 ;確定有鍵按下,則確定列鍵值碼,否則退出
AJMP KEY_EXIT
KEY_M1:
MOV P3,#0F0H
MOV A,P3
MOV KEY2,A ;列鍵值碼
ANL A,#0F0H
CJNE A,#0F0H,KEY_M2 ;如果又確定到有列鍵值碼,則查表獲得鍵值
AJMP KEY_EXIT
KEY_M2:
MOV A,KEY2
MOV R0,#KEY1
XCHD A,@R0
MOV KEYS,A
MOV R0,#00H
DISPLAY:
MOV A,R0
INC R0
MOV DPTR,#KEY_VALUE ;根據鍵碼查鍵值
MOVC A,@A+DPTR
CJNE A,KEYS,DISPLAY ;直到查到對應的鍵值
DEC R0
MOV A,R0 ;把鍵值賦值給R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV KEYS,A
MOV P2,#10H ;選通P2.4準備顯示
MOV P0,A ;把顯示碼送到P0
ACALL DELAY1S
KEY_EXIT: ;用於退出鍵盤掃描
CLR KEYCARD
RET
DELAY1S: ;延時函數
MOV R7,#10
D1:
MOV R6,#50
DJNZ R6,$
DJNZ R7,D1
RET
KEY_VALUE: ;鍵值表
DB 0EBH,0DBH,0BBH,7BH,0E7H,0D7H,0B7H,77H
TAB: ;顯示碼
DB 0xEF,0xDF,0xBF,0x7F,0xFE,0xFD,0xFB,0xF7
END
KEYS EQU 5AH ;記錄鍵值
KEY1 EQU 5BH ;記錄行掃描時的值
KEY2 EQU 5CH ;記錄列掃描時的值
ORG 0000H ;程序開始
AJMP START
ORG 30H ;爲避免佔用中斷向量區,主程序從30H開始
START:
MOV SP,#5FH ;設置堆棧的初始地址
MOV P3,#0FH ;P3,P2,P0的初始化
MOV P2,#00H
MOV P0,#0FFH
MOV KEYS,#00H ;各鍵值清0
MOV KEY1,#00H
MOV KEY2,#00H
CLR KEYCARD ;有按鍵標誌清0
LOOP: ;循環掃描鍵盤
ACALL KEY_CHECK
JNB KEYCARD,LOOP
ACALL KEY_VAL ;如果有鍵按下,則確定是哪一個鍵按下
AJMP LOOP
KEY_CHECK: ;看有沒有鍵按下
MOV A,P3
ANL A,#0FH
CJNE A,#0FH,KEY_CER ;如果讀入的與寫出的不相等,延時消抖
CLR KEYCARD
RET
KEY_CER: ;延時,再讀入,看是否真的有鍵按下
ACALL DELAY1S
MOV A,P3
ANL A,#0FH
CJNE A,#0FH,KEY_CE
CLR KEYCARD
RET
KEY_CE:
SETB KEYCARD ;真的有鍵按下,則置標誌位
RET
KEY_VAL: ;用於獲得鍵值碼
MOV P3,#0FH
MOV A,P3
MOV KEY1,A ;行鍵值碼
ANL A,#0FH
CJNE A,#0FH,KEY_M1 ;確定有鍵按下,則確定列鍵值碼,否則退出
AJMP KEY_EXIT
KEY_M1:
MOV P3,#0F0H
MOV A,P3
MOV KEY2,A ;列鍵值碼
ANL A,#0F0H
CJNE A,#0F0H,KEY_M2 ;如果又確定到有列鍵值碼,則查表獲得鍵值
AJMP KEY_EXIT
KEY_M2:
MOV A,KEY2
MOV R0,#KEY1
XCHD A,@R0
MOV KEYS,A
MOV R0,#00H
DISPLAY:
MOV A,R0
INC R0
MOV DPTR,#KEY_VALUE ;根據鍵碼查鍵值
MOVC A,@A+DPTR
CJNE A,KEYS,DISPLAY ;直到查到對應的鍵值
DEC R0
MOV A,R0 ;把鍵值賦值給R0
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV KEYS,A
MOV P2,#10H ;選通P2.4準備顯示
MOV P0,A ;把顯示碼送到P0
ACALL DELAY1S
KEY_EXIT: ;用於退出鍵盤掃描
CLR KEYCARD
RET
DELAY1S: ;延時函數
MOV R7,#10
D1:
MOV R6,#50
DJNZ R6,$
DJNZ R7,D1
RET
KEY_VALUE: ;鍵值表
DB 0EBH,0DBH,0BBH,7BH,0E7H,0D7H,0B7H,77H
TAB: ;顯示碼
DB 0xEF,0xDF,0xBF,0x7F,0xFE,0xFD,0xFB,0xF7
END