- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;由于在学习用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