沒人幫忙解決嘛,自己想辦法解決了一些問題,不會顯示亂碼了,也去掉了用二極管顯示行列狀態的部分,不過又遇到了新的問題,就是硬件仿真執行程序的時候只能連續按下4到5個鍵并正常顯示,之后再按其他鍵就沒反應了,好像死了似的,想不通,現將程序貼出來,希望有人幫忙分析,謝謝!
;***************************************************** ;矩陣鍵盤的識別,檢測是否有按鍵按下,并將其 ;鍵號通過LED數碼管顯示出來 ;***************************************************** ORG 0000H AJMP MAIN ORG 0100H MAIN : MOV 31H,#00H MOV 30H,#00H ACALL KEY ;調用鍵盤掃描子程序 ACALL SHOW0;調用判斷按鍵鍵號即數碼管顯示子程序 AJMP MAIN ;************************************************************ ;按鍵掃描子程序KEY ;************************************************************
KEY: MOV P1,#0FH; P1口低四位作輸入端,置1,高四位清0 MOV A,P1 ; 讀P1口到累加器A ANL A,#0FH ; 屏蔽高四位 XRL A,#0FH ; (A)與0FH相異或 JNZ HKEY; 判斷是否有按鍵按下,有,轉到按鍵去抖子程序 AJMP KEY ; 沒有,返回繼續掃描 HKEY : LCALL DELAY10ms;調用延時10ms子程序 MOV A,P1 ; 再讀P1口 ANL A,#0FH ; 屏蔽高四位 MOV 30H,A ; 將行線狀態放30H單元低四位寄存 XRL A,#0FH ; (A)與0FH相異或 JNZ WKEY ; 判斷是否真的有鍵按下,若是,轉到判斷哪個按鍵按下子程序 AJMP KEY ; 若不是,則返回繼續掃描 WKEY : ; 判斷列線狀態 MOV P1,#0F0H ; P1口高四位作輸入端,置1,低四位清0 MOV A,P1 ; 讀P1口到累加器A ANL A,#0F0H ; 屏蔽低四位 MOV 31H,A ; 將列線狀態放入31H暫存 XRL A,#0F0H ; JZ KEY ; 再次判斷按鍵狀態,增強識別的可*性 MOV A,31H ; 將列線狀態送回A ORL A,30H ; 將行列狀態合并 MOV 30H,A ; 放入30H ACALL DELAY10ms; 調用延時10ms子程序 RE: MOV A,P1 ; 再讀入P1口狀態 CJNE A,#0F0H,RE; 判斷按鍵是否釋放了,沒有,則等待釋放 RET ; 若釋放了,則返回
;到這邊為止經過測試是沒有問題的,讀出的行列狀態即30H中的內容是正確的,就是執行后面的程序不知道為什么會出問題!!!!! ;*************************************************************** ;判斷按鍵的鍵號及數碼管顯示子程序SHOW0 ;************************************************************** SHOW0: L1: MOV A,30H ;將檢測到得按鍵行列狀態送到A XRL A,#77H ;(A)與77H(01110111)相異或 JNZ L2 ;判斷是否是第16個鍵按下,若不是,轉到L2判斷是否是第15個鍵按下 MOV A,#0FH ;若是,則將鍵號送入A ACALL SHOW0_1;調用數碼管顯示子程序 L2: MOV A,30H ;............................... XRL A,#0B7H ;.............................. JNZ L3 MOV A,#0EH ACALL SHOW0_1 L3: MOV A,30H XRL A,#0D7H JNZ L4 MOV A,#0DH ACALL SHOW0_1 L4: MOV A,30H XRL A,#0E7H JNZ L5 MOV A,#0CH ACALL SHOW0_1 L5: MOV A,30H XRL A,#7BH JNZ L6 MOV A,#0BH ACALL SHOW0_1 L6: MOV A,30H XRL A,#0BBH JNZ L7 MOV A,#0AH ACALL SHOW0_1 L7: MOV A,30H XRL A,#0DBH JNZ L8 MOV A,#09H ACALL SHOW0_1 L8: MOV A,30H XRL A,#0EBH JNZ L9 MOV A,#08H ACALL SHOW0_1 L9: MOV A,30H XRL A,#7DH JNZ L10 MOV A,#07H ACALL SHOW0_1 L10: MOV A,30H XRL A,#0BDH JNZ L11 MOV A,#06H ACALL SHOW0_1 L11: MOV A,30H XRL A,#0DDH JNZ L12 MOV A,#05H ACALL SHOW0_1 L12: MOV A,30H XRL A,#0EDH JNZ L13 MOV A,#04H ACALL SHOW0_1 L13: MOV A,30H XRL A,#7EH JNZ L14 MOV A,#03H ACALL SHOW0_1 L14: MOV A,30H XRL A,#0BEH JNZ L15 MOV A,#02H ACALL SHOW0_1 L15: MOV A,30H XRL A,#0DEH JNZ L16 MOV A,#01H ACALL SHOW0_1 L16: MOV A,30H XRL A,#0EEH JNZ L17 ;若檢測到均不是以上鍵號對應的按鍵按下,則轉到L17返回主程序重新檢測 MOV A,#00H ACALL SHOW0_1 ;..................... L17: AJMP MAIN ;******************************************************************************** ;鍵號送數碼管顯示 ;******************************************************************************** SHOW0_1: CLR P2.0 MOV DPTR,#TAB MOVC A,@A+DPTR MOV P0,A RET DELAY10ms: MOV R6,#20 ;延時10ms子程序 LX0: MOV R7,#248h DJNZ R7,$ DJNZ R6,LX0 RET TAB: DB 0C0H,0F9H,0A4H,0B0H DB 99H,92H,82H,0F8H DB 80H,90H,88H,83H DB 0C6H,0A1H,86H,8EH END |