1. 程式人生 > >51微控制器外設之——按鍵的檢測(帶有標誌位的按鍵識別法)

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()等延時函式,因為在延時的過程中,微控制器基本上沒有什麼工作。但是這段時間對於微控制器而言,也是比較寶貴的。所以在接下來的一篇博文,將介紹另一種不需要延時消抖的按鍵掃描方式。

未完待續……