抖动)
RET
INKEY01:
LCALL GETKEYBITK;取键跳变标志
JZ INKEY02;键未发生跳变(防止2次事件处理)
LCALL CLRKEYBITX;设置重入标志
MOV A,KEYNUM;取键号
MOV DPTR,#KEYJMPPROCTABX;键盘放键事件处理表
LCALL KEYPROC;执行键盘放键事件处理
INKEY02:
RET
INKEY1:
;-------有键压下------------------------
LCALL GETKEYBIT;取键状态
JNZ INKEY11;键状态未发生变化(防止2次事件处理)
LCALL SETKEYBIT;设置压键标志
LCALL SETKEYBITK;设置跳变标志(防止压键抖动)
RET
INKEY11:
LCALL GETKEYBITK;取键跳变标志
JZ INKEY12;键未发生跳变
LCALL CLRKEYBITX;设置重入标志
MOV A,KEYNUM;取键号
MOV DPTR,#KEYJMPPROCTAB;键盘压键事件处理表
LCALL KEYPROC;执行键盘压键事件处理
INKEY12:
RET
GETKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP GETKEYBITX
GETKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
GETKEYBITX:
MOV A,@R0
ANL A,B
RET
SETKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP SETKEYBITX
SETKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
SETKEYBITX:
MOV A,@R0
ORL A,B
MOV @R0,A
RET
CLRKEYBITK:
MOV A,R0
ADD A,#12
MOV R0,A
SJMP CLRKEYBITX
CLRKEYBIT:
LCALL GETKEYBITADDR
LCALL GETKEYBITVAL
CLRKEYBITX:
MOV A,@R0
XRL B,#0FFH;取反B
ANL A,B
XRL B,#0FFH;还原B
MOV @R0,A
RET
;-----------------------------------
;CPLKEYBITK:
; MOV A,R0
; ADD A,#12
; MOV R0,A
; SJMP CPLKEYBITX
;CPLKEYBIT:
; LCALL GETKEYBITADDR
; LCALL GETKEYBITVAL
;CPLKEYBITX:
; MOV A,@R0
; XRL A,B
; MOV @R0,A
; RET
;---------------------------------------------
GETKEYBITVAL:
MOV A,KEYNUM
ANL A,#07H
ADD A,#GETKEYBITTAB-GETKEYBITTABOFF
MOVC A,@A+PC
GETKEYBITTABOFF:
MOV B,A
RET
GETKEYBITTAB:
DB 00000001B
DB 00000010B
DB 00000100B
DB 00001000B
DB 00010000B
DB 00100000B
DB 01000000B
DB 10000000B
RET
;----------------------------------------------
GETKEYBITADDR:
MOV A,KEYNUM
ANL A,#01111000B
RR A
RR A
RR A
ADD A,#KEYBUFF1
MOV R0,A
RET
;-------键测试子程序--------------------------
TESTKEY:
;键号KEYNUM=000 0000B~101 1111B(0~95)
;入口 无
;出口 ACC==0 无键压下(键号KEYNUM)
; ACC<>0 有键压下(键号KEYNUM)
MOV A,KEYNUM;取键号
ANL A,#0FH;取行号(键号低4位)
ANL P3,#0F0H;清行信号
ORL P3,A;发送行扫描信号DCBA;P3.3~P3.0
MOV A,KEYNUM;取键号
ANL A,#01110000B;取列号(键号高3位)
SWAP A;变换到低3位
ADD A,#TESTKEYTAB-TESTKEYTABOFF;得到表地址
MOVC A,@A+PC;取列表值
TESTKEYTABOFF:
JZ TESTKEYEXIT;6,7非法列,认为无键压下
PUSH B;保护现场
MOV B,A;暂存
ANL A,P1;接收列值P1.7~P1.2,有键压下为0
XRL A,B;有键压下非0
POP B;恢复现场
TESTKEYEXIT:
RET
TESTKEYTAB:
DB 00000100B;0列
DB 00001000B;1列
DB 00010000B;2列
DB 00100000B;3列
DB 01000000B;4列
DB 10000000B;5列
DB 00000000B;6列非法
DB 00000000B;7列非法
;-------定时器T0中断服务程序--------------------
;每个键20mS扫描1次,并自动进行压键或放键消抖处理
;这是1个大规模(96键)的键盘游击战的非典战例
;特点:
;1.不需键扫描.(T0中断的次序即为键扫描号)
;2.不需键消抖.(在T0中断96次后自动消抖)
;3.压键放键事件分离(散转回收技术)
;4.用户事件"并行处理"(mS级分时)
T0INTPROC:
PUSH PSW
PUSH ACC
PUSH B
PUSH DPL
PUSH DPH
T0INTPROC_START:
LCALL INKEY;键扫描并执行压放键事件处理
INC KEYNUM;准备下一键号(T0中断计数)
MOV A,KEYNUM
CJNE A,#KEYCOUNT,T0INTPROC_EXIT
MOV KEYNUM,#00H;开始下1轮键扫描
T0INTPROC_EXIT:
POP DPH
POP DPL
POP B
POP ACC
POP PSW
RETI
;-------定时器T1中断服务程序------------
T1INTPROC:
RETI
;-------0键压键事件处理---------------------
KEYPROC0:
;在此添加用户压键事件
RET
;-------1键压键事件处理---------------------
KEYPROC1:
;在此添加用户压键事件
RET
;-------2键压键事件处理---------------------
KEYPROC2:
;在此添加用户压键事件
RET
;-------95键压键事件处理---------------------
KEYPROC95:
;在此添加用户压键事件
RET
;-------0键放键事件处理---------------------
KEYPROC0X:
;在此添加用户放键事件
RET
;-------1键放键事件处理---------------------
KEYPROC1X:
;在此添加用户放键事件
RET
;-------2键放键事件处理---------------------
KEYPROC2X:
;在此添加用户放键事件
RET
;-------95键放键事件处理---------------------
KEYPROC95X:
;在此添加用户放键事件
RET
;-------全部程序结束--------------------------------------
END
|