![]() |
發(fā)布時間: 2016-11-1 23:35
正文摘要:void keyscan() { unsigned char flag; if(KEY1==0) { DelayMS(10); if(KEY1==0) ... |
yzwzfyz 發(fā)表于 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里的各位就是按鍵結(jié)果,成功與否取決于B_INPUT(后面述) XCH A, R_LASTKEY ;取并存上次鍵值 XRL A, R_LASTKEY ;與上次比較,相同? ANL A, #C_KEY ;如果有不用的鍵,就用#C_KEY常數(shù)屏蔽掉 JZ K001 ;與上次比較,相同... ;與上次不同處理:復(fù)計次退出 MOV R_TIMEKEY, #C_TIME ;不同,復(fù)鍵計次,#C_TIME計掃鍵的計次器,這里設(shè)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 ;取本次鍵標(biāo)記位 XRL A, #C_KEY ;未按的鍵值=0 ANL A, #C_KEY ;只取鍵標(biāo)記位,排除不用的鍵位(1-8個鍵) JNZ K003 ;非0,一定有鍵按下 ;未按下不處理:清長按標(biāo)記(按下未松)后退出 CLR B_KEYPUSHED ;是0,則鍵已長時未按,即鍵已松開,清松開標(biāo)記 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,無鍵有效。 程序中各參數(shù): B_INPUT: 鍵有效標(biāo)記 RB_KEY: 鍵值,通常是20H-2FH中的一個單元,可以位尋址,用起來方便。 R_LASTKEY: 上次采樣鍵值 R_TIMEKEY: 上次本次鍵值相同計次器,如計8次,對于4ms的掃鍵,=32ms B_KEYPUSHED:鍵按下未松標(biāo)記 C_KEY: 鍵屏蔽值,如:00001111B,表示高4位無鍵,低4位有鍵(P10,P11,P12,P13) C_TIME: 常數(shù)8,當(dāng)上次本次鍵值不相同時,用它復(fù)位R_TIMEKEY。 |
給你一個用了多年的程序,匯編的。領(lǐng)會實質(zhì)后自己用C寫。 |
你可以用軟件編譯一下 |
feikong 發(fā)表于 2016-11-2 18:59 不是,首先判斷按鍵有沒有按下if(KEY==0),執(zhí)行程序,在判斷按鍵有沒有彈起while(!KEY),如果彈起就跳出這個循環(huán)。 |
當(dāng)按鍵按下后,是等待按鍵恢復(fù)后在執(zhí)行功能的嗎?如while(key!=0); |
yzwzfyz 發(fā)表于 2016-11-1 23:47 按照一般來說,按鍵防抖延時5-20MS |
yzwzfyz 發(fā)表于 2016-11-1 23:42 真心不會按鍵防抖更難的。 |
按鍵按下有個彈動的過程,即會產(chǎn)生0、1若干次,持續(xù)的時間是多少呢?就是你要解決的問題。 你用DelayMS(5),DelayMS(10)來解決彈動問題的依據(jù)是什么呢? |
你的防按鍵彈動方案太初級了。 |
Powered by 單片機教程網(wǎng)