;SCANKEY.ASM扫键,有效时,置键有效B_INPUT,置键已按下未松开B_KEYPUSHED。
;下列状况无效
;1,与上次键值R_LASTKEY不同
;2,与上次键值相同时间不足R_TIMEKEY<>0(<32ms)
;3,无按键
;4,按下未松开B_KEYPUSHED=1
;影响:PSW,A,RB_KEY,R_LASTKEY ,R_TIMEKEY
SCANKEY: MOV A, P1 ;取键值1-8键都可以
MOV RB_KEY,A ;存入本次键值,如果成功RB_KEY里的各位就是按键结果,成功与否取决于B_INPUT(后面述)
XCH A, R_LASTKEY ;取并存上次键值
XRL A, R_LASTKEY ;与上次比较,相同?
ANL A, #C_KEY ;如果有不用的键,就用#C_KEY常数屏蔽掉
JZ K001 ;与上次比较,相同...
;与上次不同处理:复计次退出
MOV R_TIMEKEY, #C_TIME ;不同,复键计次,#C_TIME计扫键的计次器,这里设8,8次
SJMP K00E
;与上次相同处理:不足8次(32ms),也不处理
K001: MOV A, R_TIMEKEY ;上次与本次键值相同计次器
JZ K002 ;=0,就表示到时间了,可以决定了。
DEC R_TIMEKEY ;相同不足8次(32ms),也不处理
;与上次相同不足时间不处理
SJMP K00E
;8次相同-------------------------
;检查是否未按下
K002: MOV A, R_LASTKEY ;取本次键标记位
XRL A, #C_KEY ;未按的键值=0
ANL A, #C_KEY ;只取键标记位,排除不用的键位(1-8个键)
JNZ K003 ;非0,一定有键按下
;未按下不处理:清长按标记(按下未松)后退出
CLR B_KEYPUSHED ;是0,则键已长时未按,即键已松开,清松开标记
SJMP K00E
;键按下且达32ms以上,键否松开?
K003: JNB B_KEYPUSHED, K004 ;按下未松不处理
SJMP K00E ;键已按下不处理
;键按下且达32ms以上,键也松开了
K004: SETB B_INPUT ;否则置键有效,B_INPUT
SETB B_KEYPUSHED ;置键已按下
K00E: RET
主程序使用
1、B_INPUT=1,则RB_KEY中的键值有效,可以使用(1-8个键,通常=0的是按下了),键处理程序完成后,记得清B_INPUT=0,就可以了。
2、B_INPUT=0,无键有效。
程序中各参数:
B_INPUT: 键有效标记
RB_KEY: 键值,通常是20H-2FH中的一个单元,可以位寻址,用起来方便。
R_LASTKEY: 上次采样键值
R_TIMEKEY: 上次本次键值相同计次器,如计8次,对于4ms的扫键,=32ms
B_KEYPUSHED:键按下未松标记
C_KEY: 键屏蔽值,如:00001111B,表示高4位无键,低4位有键(P10,P11,P12,P13)
C_TIME: 常数8,当上次本次键值不相同时,用它复位R_TIMEKEY。
|