由于在學(xué)習(xí)用DS1302來做LED時(shí)鐘時(shí),發(fā)現(xiàn)開發(fā)板附的程序?qū)?a class="innerlink" href="http://ihrv.cn/tags/按鍵" title="按鍵" target="_blank">按鍵操作,很不靈活,后來在網(wǎng)上找到一篇《一個(gè)按鍵的多次擊鍵組合判別技巧》;
C51匯編的參考程序,經(jīng)學(xué)習(xí)摸索已改成C51匯編了,并已用XL400 單片;
;以下主程序演示了不同組合按鍵時(shí),分別控制P2.0-P2.5各端口的LED燈的亮滅。
;單次短擊=>P2.0/LED1
;單次長擊=>P2.1/LED2
;短擊+短擊=>P2.2/LED3
;短擊+長擊=>P2.3/LED4
;長擊+短擊=>P2.4/LED5
;長擊+長擊=>P2.5/LED6
;------------------------------------------------------------
ORG 0040H
AJMP MAIN
MAIN:
MOV P1,#0FFH
MOV P2,#0FFH ;初始化端口
LOOP:
CALL SREAD_KEY ;讀單按鍵--子程序
MOV R0,KEY_NUM
CJNE R0,#00000010B,MAIN1 ;比較鍵值不等跳
CPL LED1_6.0 ;取反P2.0
MAIN1:
CJNE R0,#00000011B,MAIN2 ;比較鍵值不等跳
CPL LED1_6.1 ;取反P2.1
MAIN2:
CJNE R0,#00000100B,MAIN3 ;比較鍵值不等跳
CPL LED1_6.2 ;取反P2.2
MAIN3:
CJNE R0,#00000101B,MAIN4 ;比較鍵值不等跳
CPL LED1_6.3 ;取反P2.3
MAIN4:
CJNE R0,#00000110B,MAIN5 ;比較鍵值不等跳
CPL LED1_6.4 ;取反P2.4
MAIN5:
CJNE R0,#00000111B,MAIN_EXIT ;比較鍵值不等跳
CPL LED1_6.5 ;取反P2.5
MAIN_EXIT:
JMP LOOP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;讀單按鍵--子程序
;子程序執(zhí)行后返回值KEY_NUM即鍵值
;-----------------------------說明----------------------------
;短擊:鍵按下時(shí)間<500MS
;長擊:鍵按下時(shí)間>500MS
;兩次按鍵間隔時(shí)間<700MS
;鍵值定義:
;KEY_NUM="00000000": 無鍵按下
;KEY_NUM="00000001": 無意義
;KEY_NUM="00000010": 單次短擊
;KEY_NUM="00000011": 單次長擊
;KEY_NUM="00000100": 短擊+短擊
;KEY_NUM="00000101": 短擊+長擊
;KEY_NUM="00000110": 長擊+短擊
;KEY_NUM="00000111": 長擊+長擊
;KEY_NUM="00001000": 短擊+短擊+短擊
;KEY_NUM="00001001": 短擊+短擊+長擊
;KEY_NUM="00001011": 短擊+長擊+長擊
;KEY_NUM="00001111": 長擊+長擊+長擊
;以編碼從左看起第一個(gè)1看作為分界線,左邊為0、而右邊的0和1表示為:
;0短擊1長擊。
;以上組合已足夠用了!
;*************************************************************
; KEY EQU P1.0
; KEY_NUM EQU 20H
;*************************************************************
SREAD_KEY:
MOV KEY_NUM,#00H ;鍵值清0
JB KEY,SKEY_EXIT ;鍵未按下跳
CALL DL10MS ;延時(shí)去抖動(dòng)
JB KEY,SKEY_EXIT ;鍵未按下跳
MOV KEY_NUM,#1 ;置鍵值為#00000001B
SKEY_A:
MOV R0,#00H ;清計(jì)數(shù)器
CLR C ;清CY
SKEY_B:
CALL DL10MS
INC R0
MOV A,#50
SUBB A,R0
JC SKEY_C ;當(dāng)鍵按下>500MS跳
JNB KEY,SKEY_B ;鍵未釋放跳
CALL DL10MS ;延時(shí)去抖動(dòng)
JNB KEY,SKEY_B ;鍵未釋放跳
CLR C ;CY置0
JMP SKEY_D
SKEY_C:
JNB KEY,$ ;鍵未釋放停
CALL DL10MS ;延時(shí)去抖動(dòng)
JNB KEY,$ ;鍵未釋放停
SETB C ;CY置1
SKEY_D:
MOV A,KEY_NUM
RLC A ;鍵值左移一位,C->鍵值低位
MOV KEY_NUM,A
JB KEY_NUM.2,SKEY_EXIT ;判斷按鍵檢測(cè)是否完成,完成跳
;說明:KEY_NUM.1時(shí)只判斷單次按鍵兩種組合,KEY_NUM.2時(shí)可判斷兩次按鍵4種組合+單次按鍵的2種組合=6種,以此類推。
MOV R0,#00H ;清計(jì)數(shù)器
CLR C ;CY置0
SKEY_E:
CALL DL10MS
INC R0
MOV A,#70
SUBB A,R0
JC SKEY_EXIT ;當(dāng)未按下>700MS跳出
JB KEY,SKEY_E ;鍵釋放跳
CALL DL10MS ;延時(shí)去抖動(dòng)
JB KEY,SKEY_E ;鍵釋放跳
JMP SKEY_A ;當(dāng)未按下<700MS再次檢測(cè)
SKEY_EXIT:
RET
;************************************************************
;延時(shí)10mS
;************************************************************
DL10ms:
MOV R5,#14H ;20 ;10.262ms=20*511+2*20+1=20.261
TIME10MS_1:
MOV R6,#0FFH ;255 ;511us=255*2+1
DJNZ R6,$
DJNZ R5,TIME10MS_1
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
END