一個按鍵的多次擊鍵組合判別技巧彙編程序

admin @ 2014-03-25 , reply:0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;由於在學慣用DS1302來做LED時鐘時,發現開發板附的程序對按鍵操作 ;
;很不靈活,後來在網上找到一篇《一個按鍵的多次擊鍵組合判別技巧》;
;網址為HTTP://BLOG.21IC.COM/USER1/349/ARCHIVES/2005/669.HTM感覺;
;作者的點子不錯,但本人不懂義隆單片機的彙編,在網上找不到相關  ;
;C51彙編的參考程序,經學習摸索已改成C51彙編了,並已用XL400 單片;
;機編程實驗開發板,測試OK。現供大家參考。           ;
;                         作者:煥然                           ;
;                        QQ:171586392                          ;
;                         2009.12.19                           ;       
;                    轉載請說明來源,謝謝!                    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 KEY EQU P1.0
 KEY_NUM EQU 20H
 LED1_6 EQU P2
;---------------------------------------------------------------
;以下主程序演示了不同組合按鍵時,分別控制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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;讀單按鍵--子程序
;子程序執行后返回值KEY_NUM即鍵值
;-----------------------------說明----------------------------
;短擊:鍵按下時間<500MS
;長擊:鍵按下時間>500MS
;兩次按鍵間隔時間<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":  長擊+長擊+長擊
;以編碼從左看起第一個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  ;延時去抖動
 JB KEY,SKEY_EXIT ;鍵未按下跳
 MOV KEY_NUM,#1  ;置鍵值為#00000001B
SKEY_A:
 MOV R0,#00H  ;清計數器
 CLR C   ;清CY
SKEY_B:
 CALL DL10MS
 INC R0
 MOV A,#50
 SUBB A,R0
 JC SKEY_C  ;當鍵按下>500MS跳
 JNB KEY,SKEY_B  ;鍵未釋放跳
 CALL DL10MS  ;延時去抖動
 JNB KEY,SKEY_B  ;鍵未釋放跳
 CLR C   ;CY置0
 JMP SKEY_D
SKEY_C:
 JNB KEY,$  ;鍵未釋放停
 CALL DL10MS  ;延時去抖動
 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 ;判斷按鍵檢測是否完成,完成跳
 ;說明:KEY_NUM.1時只判斷單次按鍵兩種組合,KEY_NUM.2時可判斷兩次按鍵4種組合+單次按鍵的2種組合=6種,以此類推。
 MOV R0,#00H  ;清計數器
 CLR C   ;CY置0
SKEY_E:
 CALL DL10MS
 INC R0
 MOV A,#70
 SUBB A,R0
 JC SKEY_EXIT  ;當未按下>700MS跳出
 JB KEY,SKEY_E  ;鍵釋放跳
 CALL DL10MS  ;延時去抖動
 JB KEY,SKEY_E  ;鍵釋放跳
 JMP SKEY_A  ;當未按下<700MS再次檢測
SKEY_EXIT:
 RET 
;************************************************************  
;延時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 


[admin via 研發互助社區 ] 一個按鍵的多次擊鍵組合判別技巧彙編程序已經有2187次圍觀

http://cocdig.com/docs/show-post-42049.html