yzwzfyz 发表于 2016-11-1 23:47 延时去除抖动 |
;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。 |
给你一个用了多年的程序,汇编的。领会实质后自己用C写。 |
你可以用软件编译一下 |
feikong 发表于 2016-11-2 18:59 不是,首先判断按键有没有按下if(KEY==0),执行程序,在判断按键有没有弹起while(!KEY),如果弹起就跳出这个循环。 |
当按键按下后,是等待按键恢复后在执行功能的吗?如while(key!=0); |
yzwzfyz 发表于 2016-11-1 23:47 按照一般来说,按键防抖延时5-20MS |
yzwzfyz 发表于 2016-11-1 23:42 真心不会按键防抖更难的。 |
按键按下有个弹动的过程,即会产生0、1若干次,持续的时间是多少呢?就是你要解决的问题。 你用DelayMS(5),DelayMS(10)来解决弹动问题的依据是什么呢? |
你的防按键弹动方案太初级了。 |