獨立按鍵的掃描方法(延時,消抖的方法),可見這種方法很大程度上可以實現(xiàn)按鍵的準確掃描。但是仔細一看,可以發(fā)現(xiàn),它有一個缺點——存在while語句的松手檢測!
試想,倘若我們一直按著按鍵不松手,那我們的程序毫無疑問的一直卡在了while語句的松手檢測上。這在很多場合是并不適用的。
對于獨立按鍵的博文中所提到的配合數(shù)碼管顯示的實例中,由于我們數(shù)碼管顯示函數(shù)display() 位于主函數(shù)中,假如我們按鍵長時間按下,一定會存在數(shù)碼管不能顯示的情況。所以接下來給出一種不需要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() //按鍵掃描函數(shù)
{
if((s4 == 0) && (!key_flag)) //如果有鍵按下,則條件成立(有鍵按下,則s4為0;而 !key_flag為1)
{
delay10ms(); //延時消抖
key_flag = 1; //把標志位置為1
if(s4 == 0) //如果確定有鍵按下
{
dspbuf[0]++; //進行事件處理(數(shù)碼管顯示值加1)
}
}
else if(s4 != 0) //未按下按鍵
{
key_flag = 0;
}
}123456789101112131415161718
其中:
代碼“key_flag = 1”的作用是:下次即便按鍵沒有松手,程序跑完一圈之后,也不會再滿足if((s4 == 0) && (!key_flag))的條件;同樣,亦不會滿足else if(s4 != 0)的條件,那么key_flag 不會被賦為0。綜合以上情況,一次按鍵只會進行一次處理。當按鍵被釋放后,以后的掃描則會滿足else if(s4 != 0)的條件,那么key_flag 會被賦為0,則可以進行接下來的按鍵掃描了,如此反復……
綜上所述,這樣的按鍵處理,讓程序減少了while的松手檢測,這對于程序是十分有利的。試想,單片機有那么多的程序要處理,但是卻因為按鍵而卡在一個地方,這確實有點得不償失了。
而在單片機程序執(zhí)行的過程中,我們也要盡可能的少用delay()等延時函數(shù),因為在延時的過程中,單片機基本上沒有什么工作。但是這段時間對于單片機而言,也是比較寶貴的。