基于標(biāo)志位的獨(dú)立按鍵掃描方法分析
獨(dú)立按鍵的掃描方法(延時(shí),消抖的方法),可見(jiàn)這種方法很大程度上可以實(shí)現(xiàn)按鍵的準(zhǔn)確掃描。但是仔細(xì)一看,可以發(fā)現(xiàn),它有一個(gè)缺點(diǎn)——存在while語(yǔ)句的松手檢測(cè)!
試想,倘若我們一直按著按鍵不松手,那我們的程序毫無(wú)疑問(wèn)的一直卡在了while語(yǔ)句的松手檢測(cè)上。這在很多場(chǎng)合是并不適用的。
對(duì)于獨(dú)立按鍵的博文中所提到的配合數(shù)碼管顯示的實(shí)例中,由于我們數(shù)碼管顯示函數(shù)display() 位于主函數(shù)中,假如我們按鍵長(zhǎng)時(shí)間按下,一定會(huì)存在數(shù)碼管不能顯示的情況。所以接下來(lái)給出一種不需要while松手檢測(cè)的按鍵掃描——帶有標(biāo)志位的按鍵識(shí)別(在矩陣鍵盤(pán)同樣適用,這里以獨(dú)立鍵盤(pán)為例)。
首先附上原理圖:
用跳帽連接排針 J5 的2腳與3腳,將鍵盤(pán)設(shè)置為獨(dú)立按鍵(只有S4~S7有效)。此時(shí),S4~S7一端分別與P3^3~P3^0相連,另一端連向GND。
其核心代碼如下,以按下 S4 為例:
sbit s4 = P3^3;
uchar key_flag = 0; //首先定義按鍵的標(biāo)志位,并初始化為0
void key_scan() //按鍵掃描函數(shù)
{
if((s4 == 0) && (!key_flag)) //如果有鍵按下,則條件成立(有鍵按下,則s4為0;而 !key_flag為1)
{
delay10ms(); //延時(shí)消抖
key_flag = 1; //把標(biāo)志位置為1
if(s4 == 0) //如果確定有鍵按下
{
dspbuf[0]++; //進(jìn)行事件處理(數(shù)碼管顯示值加1)
}
}
else if(s4 != 0) //未按下按鍵
{
key_flag = 0;
}
}123456789101112131415161718
其中:
代碼“key_flag = 1”的作用是:下次即便按鍵沒(méi)有松手,程序跑完一圈之后,也不會(huì)再滿(mǎn)足if((s4 == 0) && (!key_flag))的條件;同樣,亦不會(huì)滿(mǎn)足else if(s4 != 0)的條件,那么key_flag 不會(huì)被賦為0。綜合以上情況,一次按鍵只會(huì)進(jìn)行一次處理。當(dāng)按鍵被釋放后,以后的掃描則會(huì)滿(mǎn)足else if(s4 != 0)的條件,那么key_flag 會(huì)被賦為0,則可以進(jìn)行接下來(lái)的按鍵掃描了,如此反復(fù)……
綜上所述,這樣的按鍵處理,讓程序減少了while的松手檢測(cè),這對(duì)于程序是十分有利的。試想,單片機(jī)有那么多的程序要處理,但是卻因?yàn)榘存I而卡在一個(gè)地方,這確實(shí)有點(diǎn)得不償失了。
而在單片機(jī)程序執(zhí)行的過(guò)程中,我們也要盡可能的少用delay()等延時(shí)函數(shù),因?yàn)樵谘訒r(shí)的過(guò)程中,單片機(jī)基本上沒(méi)有什么工作。但是這段時(shí)間對(duì)于單片機(jī)而言,也是比較寶貴的。