一个按键的多次击键组合判别技巧汇编程序 |
时间:2013-09-01 来源:123485.com 作者:9stone |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;由于在学习用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
|
|
|
|