;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。
|