51微控制器外設之——按鍵的檢測(帶有標誌位的按鍵識別法)
前面提到了獨立按鍵的掃描方法(延時,消抖的方法),可見這種方法很大程度上可以實現按鍵的準確掃描。但是仔細一看,可以發現,它有一個缺點——存在while語句的鬆手檢測!
試想,倘若我們一直按著按鍵不鬆手,那我們的程式毫無疑問的一直卡在了while語句的鬆手檢測上。這在很多場合是並不適用的。
對於獨立按鍵的博文中所提到的配合數碼管顯示的例項中,由於我們數碼管顯示函式display() 位於主函式中,假如我們按鍵長時間按下,一定會存在數碼管不能顯示的情況。所以接下來給出一種不需要while鬆手檢測的按鍵掃描——帶有標誌位的按鍵識別(在矩陣鍵盤同樣適用,這裡以獨立鍵盤為例)。
首先附上原理圖:
用跳帽連線排針 J5 的2腳與3腳,將鍵盤設定為獨立按鍵(只有S4~S7有效)。此時,S4~S7一端分別與P3^3~P3^0相連,另一端連向GND。
其核心程式碼如下,以按下 S4 為例:
sbit s4 = P3^3;
uchar key_flag = 0; //首先定義按鍵的標誌位,並初始化為0
void key_scan() //按鍵掃描函式
{
if((s4 == 0) && (!key_flag)) //如果有鍵按下,則條件成立(有鍵按下,則s4為0;而 !key_flag為1)
{
delay10ms(); //延時消抖
key_flag = 1; //把標誌位置為1
if(s4 == 0) //如果確定有鍵按下
{
dspbuf[0]++; //進行事件處理(數碼管顯示值加1)
}
}
else if(s4 != 0 ) //未按下按鍵
{
key_flag = 0;
}
}
其中:
程式碼“key_flag = 1”的作用是:下次即便按鍵沒有鬆手,程式跑完一圈之後,也不會再滿足if((s4 == 0) && (!key_flag))的條件;同樣,亦不會滿足else if(s4 != 0)的條件,那麼key_flag 不會被賦為0。綜合以上情況,一次按鍵只會進行一次處理。當按鍵被釋放後,以後的掃描則會滿足else if(s4 != 0)的條件,那麼key_flag 會被賦為0,則可以進行接下來的按鍵掃描了,如此反覆……
綜上所述,這樣的按鍵處理,讓程式減少了while的鬆手檢測,這對於程式是十分有利的。試想,微控制器有那麼多的程式要處理,但是卻因為按鍵而卡在一個地方,這確實有點得不償失了。
而在微控制器程式執行的過程中,我們也要儘可能的少用delay()等延時函式,因為在延時的過程中,微控制器基本上沒有什麼工作。但是這段時間對於微控制器而言,也是比較寶貴的。所以在接下來的一篇博文,將介紹另一種不需要延時消抖的按鍵掃描方式。
未完待續……