按键处理技巧(状态机)
生活随笔
收集整理的這篇文章主要介紹了
按键处理技巧(状态机)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)載原文:https://blog.csdn.net/guohengsheng3882/article/details/78506314
按鍵是單片機最常用的輸入設(shè)備了。按下接通,松開分?jǐn)?#xff0c;本來是 很簡單的事情,由于現(xiàn)在我們使用的單片機實在是一個非常高速的裝置,由于它的高速,使得本來不被人們重視的機械觸點在接通和斷開瞬間的多次快速彈跳問題變 得突出起來。常規(guī)的方法就是一旦發(fā)現(xiàn)按鍵動作,就人為加上10-20毫秒的延時,等觸點穩(wěn)定下來以后再進(jìn)行按鍵處理(例如判斷按鍵碼)。同時為了不至于把 一次按鍵當(dāng)做多次按鍵,通常就是等待按鍵確實釋放以后再執(zhí)行鍵碼對應(yīng)的程序。詳細(xì)過程參見版主的“事無巨細(xì),獨立按鍵”文。延時法簡單實用,編程也容易,使用非常普遍。但是這個辦法有些缺點,1是加上延時后,在延時期間單片機什么也沒干,就在那里兜圈子耗時間,如果這時有其他事情需要處理也只好放一放,降低了運行 效率。2是對一些需要較復(fù)雜按鍵功能的情況例如區(qū)別長按鍵和短按鍵難于實現(xiàn)。那么其他的辦法是有,例如中斷法,不按鍵就不查詢,直到按鍵觸發(fā)外部中斷。但是單片機通常外部中斷口很少而按鍵較多,給應(yīng)用造成不便。下面就介紹一個新的按鍵查詢方法:狀態(tài)機法。說明如下: 1,給按鍵設(shè)定3種狀態(tài):狀態(tài)0:無按鍵,狀態(tài)1:已經(jīng)按下,狀態(tài)2:已經(jīng)釋放。按鍵可以一直處于狀態(tài)0,也可以由狀態(tài)0轉(zhuǎn)為狀態(tài)1,也可以由狀態(tài)1轉(zhuǎn)為 狀態(tài)2,然后恢復(fù)到狀態(tài)0。如此順序循環(huán)。 2,通過定時(例如定時器中斷)每隔一段時間(例如10毫秒)檢查一下按鍵 狀態(tài),根據(jù)上次檢查的狀態(tài)和當(dāng)前的狀態(tài)比較,來確定應(yīng)該做什么。在上述時間間隔內(nèi),單片機就可以執(zhí)行其他任務(wù)。一旦確認(rèn)按鍵成立,就可以立即找出鍵碼并進(jìn) 行隨后的鍵碼處理程序而無需等待按鍵釋放,加上適當(dāng)?shù)奶幹靡部梢詫Ρ容^復(fù)雜的按鍵進(jìn)行處理。下面以一個具體的程序,詳細(xì)解釋怎么實現(xiàn):讀鍵函數(shù)readkey()。無參數(shù),返回鍵碼。4個按鍵連接在PC0…PC3引腳 ///定時器溢出中斷用于定時查鍵 大約10毫秒中斷一次 keyscan_t=0;? ?? ? //這個全局變量是個定時器標(biāo)志,定時中斷置1,外部清0 ISR(TIMER0_OVF_vect)? {?TCNT0=216;? ?? ?? ?程序啟動后設(shè)TCCR0=0X04;256分頻,每(256-216)*256微秒中斷一次keyscan_t=1;? ?? ? 定時時間到標(biāo)志置1PORTD=dispdata; 其它刷新顯示功能和按鍵處理無關(guān) }?讀鍵函數(shù)uchar readkey(void)? {?uchar keyval=0;??//keyvai是最終鍵碼,4個按鍵分別對應(yīng)的鍵碼是0x0e,0x0d,0x0b,0x07uchar newkey;? ?? ?newkey是當(dāng)前鍵碼,需要和上次鍵碼比較static uchar keystate=0; 狀態(tài)值,起始為0,注意它是靜態(tài)變量賦值后就保持到改寫為止uchar keyOK;? ?? ???/確認(rèn)按鍵static uchar lastkey; /lastkey記錄上次檢查時的鍵碼,也是靜態(tài)變量newkey=PINC&0X0F; /鍵碼就是PC口低4位取值每次都要讀取switch(keystate)? ?? ???//按照狀態(tài)值進(jìn)行不同的處理,單片機啟動后總是狀態(tài)0,{?case 0:? ?? ?? ?? ?? ?? ?? ? /狀態(tài)0? ?? ?? ?? ??if(newkey!=0x0f)? ?? ? //如果有鍵{?keystate=1;? ?? ?? ?? ?? ?//有鍵記下狀態(tài)1lastkey=newkey;? ?? ???/有鍵就用當(dāng)前鍵碼代替原來鍵碼等待下次檢查}?break;? ?? ?? ?? ?? ?? ?? ?? ???//如果無鍵直接跳出,有鍵進(jìn)行上述處理后跳出,注意有鍵狀態(tài)值已變case 1:? ?? ?? ?? ?? ?? ?? ???///如上次有鍵,這次就轉(zhuǎn)到狀態(tài)1if(newkey==lastkey)? ?/這次讀取的鍵值如果和上次記錄的一樣,就是確認(rèn)按鍵了{(lán)?keyOK=1;? ?? ?? ?? ?? ?? ???//置位按鍵標(biāo)志keyval=newkey;? ?? ?? ? /取得鍵碼keystate=2;? ?? ?? ?? ?? ? //按鍵狀態(tài)下次要轉(zhuǎn)狀態(tài)2}?else? ?? ?? ?? ?? ?? ?? ???//如果讀鍵和上次不同,不確認(rèn)按鍵,除了不進(jìn)行以上處理還要把狀態(tài)值清0keystate=0;?break;? ?? ?? ?? ?? ?? ? .///跳出case 2:? ?? ?? ?? ?? ???/狀態(tài)2if(newkey==0x0f)? ?///如果10毫秒后仍然無鍵keystate=0;? ?? ?? ?? ?//下次回到狀態(tài)0break;? ?? ?? ?? ?? ?? ?? ??}?return keyval;? ?? ?返回鍵碼 }?以上就是在調(diào)頻收音機里使用的獲取鍵碼程序。每10余毫秒定時中斷一次就執(zhí)行一次。?
總結(jié)
以上是生活随笔為你收集整理的按键处理技巧(状态机)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言程序设计基础及应用实例---第二节
- 下一篇: JAVA JDK+Eclipse IDE