没人帮忙解决嘛,自己想办法解决了一些问题,不会显示乱码了,也去掉了用二极管显示行列状态的部分,不过又遇到了新的问题,就是硬件仿真执行程序的时候只能连续按下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 |