劉 宸
(四川職業(yè)技術(shù)學(xué)院電子電氣工程系,四川 遂寧 629000)
兩種基于電平計(jì)時(shí)的按鍵檢測(cè)方法
劉 宸
(四川職業(yè)技術(shù)學(xué)院電子電氣工程系,四川 遂寧 629000)
在電子設(shè)備中,按鍵是較常用的輸入設(shè)備之一,機(jī)械式按鍵在按下和釋放時(shí)在一定時(shí)間內(nèi)會(huì)產(chǎn)生機(jī)械抖動(dòng),使得輸出電平不穩(wěn)定,從而會(huì)導(dǎo)致程序的錯(cuò)誤動(dòng)作.為了消除抖動(dòng),通常使用軟件消抖.本文以幾種按鍵檢測(cè)程序?qū)Ρ人鼈兊奶攸c(diǎn)及應(yīng)用場(chǎng)合,總結(jié)出一種對(duì)電平計(jì)時(shí)的程序算法是更具通用性、效率更高和多任務(wù)實(shí)時(shí)響應(yīng)更優(yōu)的方法.
按鍵;程序;消抖
許多電子設(shè)備鍵盤常使用機(jī)械觸點(diǎn)式按鍵開關(guān),其主要功能是把機(jī)械上的通斷轉(zhuǎn)換成為電氣上的邏輯關(guān)系.機(jī)械式按鍵在按下和釋放時(shí),由于機(jī)械彈性作用的影響,通常伴隨有一定時(shí)間的觸點(diǎn)機(jī)械抖動(dòng),然后其觸點(diǎn)才能穩(wěn)定下來.這種機(jī)械抖動(dòng)會(huì)使輸出電平不穩(wěn)定,如圖1所示.抖動(dòng)時(shí)間的長(zhǎng)短與按鍵的機(jī)械特性和按鍵力度有關(guān),一般為5~10 ms.按下按鍵的閉合穩(wěn)定時(shí)間通常大于100 ms.
圖1 按鍵觸點(diǎn)的機(jī)械抖動(dòng)示意
輸出電平的不穩(wěn)定,可能導(dǎo)致程序誤判.即按鍵一次按下或釋放被錯(cuò)誤地認(rèn)為是多次操作,這種情況是不允許出現(xiàn)的.為了克服按鍵觸點(diǎn)機(jī)械抖動(dòng)所致的檢測(cè)誤判,必須采取消抖措施.消除電平抖動(dòng)可從硬件電路或軟件控制兩方面實(shí)現(xiàn).在鍵數(shù)較少時(shí),可采用硬件消抖,讓程序控制十分簡(jiǎn)單,如單次脈沖發(fā)生電路.當(dāng)按鍵數(shù)量較多時(shí),通常采用軟件消抖來達(dá)到同樣可靠的效果,成本低廉.對(duì)應(yīng)的有多種按鍵檢測(cè)程序,本文接下來對(duì)比它們的優(yōu)缺點(diǎn)及應(yīng)用場(chǎng)合,探尋最優(yōu)的解決方案.本文示例程序用C 51語言編寫來說明算法,其他單片機(jī)開發(fā)環(huán)境均可參照此算法來實(shí)現(xiàn).
傳統(tǒng)按鍵檢測(cè)程序如圖2所示,是一種簡(jiǎn)單的軟件消抖流程.首先檢測(cè)按鍵是否按下,如果沒有按鍵按下,則跳過這段程序.如果有鍵按下,通過調(diào)用10 ms延時(shí)函數(shù),使按鍵可能抖動(dòng)的時(shí)間不做任何操作,待按鍵電平穩(wěn)定后,再次判斷鍵是否按下.如果第二次判斷時(shí),按鍵是按下狀態(tài),就表示有鍵可靠地按下,否則表示第一次檢測(cè)到的是干擾信號(hào)或者為按鍵釋放時(shí)的抖動(dòng).如果第二次判斷時(shí),沒有按鍵按下,就應(yīng)該跳過執(zhí)行按鍵功能程序.
在確定有鍵按下的情況下,根據(jù)按鍵的功能,執(zhí)行相應(yīng)的按鍵處理程序.為了確保每次按鍵按下時(shí)僅做一次操作,還要等待按鍵松開,也就是要再進(jìn)行按鍵檢測(cè),有鍵按下則表示按鍵未松開,需要繼續(xù)循環(huán)檢測(cè),直到按鍵松開為止,結(jié)束按鍵的處理.
圖2傳統(tǒng)檢測(cè)按鍵流程圖
圖2 對(duì)應(yīng)的程序段如下所示.
void inkey()
{ uchar i;
uchark;//存儲(chǔ)鍵值的臨時(shí)變量
k=P1IN&0xC0;//讀鍵盤端口
if(k!=0xC0)//第一次判斷是否按下鍵
{//如果按下鍵,則要進(jìn)一步判斷和處理
delay10ms();//調(diào)用延時(shí)函數(shù),使按鍵抖動(dòng)時(shí)間過去
if(k==(P1IN&0xC0))//與第一次檢測(cè)相同,則表示有鍵穩(wěn)定按下
{key act(k);//執(zhí)行按鍵功能
while(k==(P1IN&0xC0));//鍵未松開,繼續(xù)循環(huán)檢測(cè)
}}
這段程序能夠較好地實(shí)現(xiàn)按鍵消抖,如果系統(tǒng)為“按鍵”+“數(shù)碼管靜態(tài)顯示”或“按鍵”+“LCD 顯示”,使用這樣的檢測(cè)方法是可以的.但在等待按鍵松開時(shí)和消抖延時(shí)內(nèi),程序是停在這的,不能處理其他實(shí)時(shí)任務(wù),如動(dòng)態(tài)顯示、傳感器檢測(cè)等.即便可以利用中斷系統(tǒng)處理其他實(shí)時(shí)任務(wù),而讓主程序來檢測(cè)按鍵,那么會(huì)無法進(jìn)入休眠模式,導(dǎo)致功耗太高.當(dāng)然,也可把這段按鍵檢測(cè)放在中斷里,那么由于中斷優(yōu)先級(jí)的問題,也會(huì)因程序停在這里導(dǎo)致無法運(yùn)行其他任務(wù).
傳統(tǒng)方法的按鍵檢測(cè)與其它實(shí)時(shí)任務(wù)的運(yùn)行存在矛盾,有諸多弊端,本文提出的對(duì)電平計(jì)時(shí)的按鍵檢測(cè)方法可以解決這些問題. 程序流程圖如圖3所示,每隔幾個(gè)ms讀取一次按鍵值,可以放在主函數(shù)如圖3(a),也可放在定時(shí)中斷函數(shù)里,只要間隔時(shí)間是幾個(gè)ms左右,目的是在時(shí)間上抽樣檢測(cè)引腳電平.
讀取鍵值的方法如圖3(b),讀取端口數(shù)據(jù),判斷有無按鍵,有鍵按下時(shí)出現(xiàn)低電平則計(jì)時(shí)+1,由于是間隔時(shí)間抽樣檢測(cè)按鍵,這個(gè)統(tǒng)計(jì)的計(jì)時(shí)值就能表征低電平保持的時(shí)間. 若連續(xù)多次都檢測(cè)到低電平,則表示已經(jīng)度過抖動(dòng)時(shí)間,穩(wěn)定按住按鍵.將按住按鍵20 ms時(shí)視為短按有效,若間隔時(shí)間是2 ms,則計(jì)時(shí)值則為10次,當(dāng)計(jì)時(shí)值達(dá)到10時(shí)滿足短按條件,就可返回鍵值,執(zhí)行相應(yīng)按鍵功能.當(dāng)計(jì)時(shí)值達(dá)到500,即按住了500*2 ms=1 s,視為長(zhǎng)按,此時(shí)將計(jì)時(shí)值回?fù)艿?00,并返回鍵值執(zhí)行相應(yīng)功能.當(dāng)繼續(xù)長(zhǎng)按住按鍵,計(jì)時(shí)值從400增大到500時(shí),再次滿足長(zhǎng)按條件,但觸發(fā)的周期只有(500-400)*2 ms=200 ms,即長(zhǎng)按1秒后每隔0.2秒就執(zhí)行一次,實(shí)現(xiàn)了電視遙控器上的連加連減的效果.返回鍵值的時(shí)間點(diǎn)只有10(短按)和500(長(zhǎng)按),太小的是按鍵抖動(dòng)時(shí)期,其他次數(shù)都不滿足按鍵條件,都返回按鍵無效的鍵值.當(dāng)釋放按鍵或抖動(dòng)時(shí),計(jì)時(shí)值清0,讓計(jì)時(shí)值構(gòu)成一個(gè)循環(huán).整個(gè)檢測(cè)按鍵的程序里沒有延時(shí)和等待,因此程序不會(huì)停留在這里,方便進(jìn)行其它任務(wù)的處理.
圖3 對(duì)電平計(jì)時(shí)的按鍵檢測(cè)方法
讀取按鍵值的程序如下:
uchar in key() //讀鍵盤
{ uchark;
staticuint cnt=0;//計(jì)時(shí)值,用靜態(tài)變量存儲(chǔ)以保存上次的值
k=P 3;
if(k!=0 x f f)//按鍵
{
cnt++; // 按間隔時(shí)間對(duì)低電平計(jì)數(shù)if (cnt==10) {return k;} //10*2ms=20ms 已經(jīng)按住
else if(cnt〉500)//500*2ms=1s 長(zhǎng)按
{cnt=400;return k;}// 實(shí)現(xiàn)長(zhǎng)按累加else return 0xff; // 其他次數(shù),不滿足條件
}
else {cnt=0;return 0xff;}// 沒按鍵時(shí),cnt 清0
}
上述對(duì)電平計(jì)時(shí)的按鍵檢測(cè)方法能實(shí)現(xiàn)長(zhǎng)按累加,但是不能區(qū)分短按和長(zhǎng)按的鍵值,那么按鍵的功能是相同的,通過更改長(zhǎng)按的鍵值也可實(shí)現(xiàn)短按和長(zhǎng)按的不同功能,但是由于計(jì)時(shí)值從0逐漸增加到10再到500,長(zhǎng)按的過程中經(jīng)過短按的計(jì)時(shí)值,會(huì)造成執(zhí)行長(zhǎng)按功能之前必定執(zhí)行一次短按的功能.在需要嚴(yán)格區(qū)分短按和長(zhǎng)按功能的應(yīng)用場(chǎng)合,這是不允許的,因此可進(jìn)一步改進(jìn).方法是:長(zhǎng)按是按住不放的,應(yīng)在按鍵時(shí)判斷,而短按的識(shí)別應(yīng)放在釋放按鍵時(shí)判斷,這樣就保證了執(zhí)行長(zhǎng)按功能前不會(huì)執(zhí)行短按功能.
uchar inkey() // 讀鍵盤
{ uchar k;
static uint cnt=0,last_k;
k=P3;
if(k!=0xff)// 按鍵
{ last_k=k;// 保存上次按下的鍵值
cnt++;
if(cnt〉230) return 0x99;// 長(zhǎng)按執(zhí)行不同功能
else return 0xff;
}
else//釋放時(shí)判斷短按
{ if (10〈cnt&&cnt〈200)k=last_k;
//10〈cnt〈200,視為短按
elsek=0xff;
cnt=0;returnk;//沒按鍵時(shí),cnt清0
}
}
經(jīng)過仿真實(shí)驗(yàn)和真實(shí)硬件電路的反復(fù)測(cè)試,實(shí)驗(yàn)結(jié)果證明本文提出的對(duì)電平計(jì)時(shí)的按鍵檢測(cè)方法既能夠可靠地消除前沿和后沿抖動(dòng),又能夠保證程序順暢地運(yùn)行多任務(wù).而改進(jìn)的按鍵檢測(cè)方法在此基礎(chǔ)上更進(jìn)一步能嚴(yán)格區(qū)分短按和長(zhǎng)按的功能.顯示出這兩種方法的優(yōu)越性.
綜上,傳統(tǒng)方法的按鍵檢測(cè)與其它實(shí)時(shí)任務(wù)的運(yùn)行存在諸多矛盾和弊端,如無法進(jìn)入休眠模式,或放在中斷里,由于中斷優(yōu)先級(jí)的問題,也會(huì)因程序停留導(dǎo)致無法運(yùn)行其他任務(wù).本文提出的對(duì)電平計(jì)時(shí)的按鍵檢測(cè)方法可以解決這些問題,但是不能區(qū)分短按和長(zhǎng)按的功能,進(jìn)一步改進(jìn)為按住時(shí)判斷長(zhǎng)按,釋放時(shí)判斷短按,從而實(shí)現(xiàn)執(zhí)行長(zhǎng)按功能前不會(huì)執(zhí)行短按功能,保證了短按和長(zhǎng)按功能的嚴(yán)格區(qū)分,是通用性和效率更高的方法.
[1]成友才.單片機(jī)應(yīng)用技術(shù)[M].成都:西南交通大學(xué)出版社,2014.
[2]施保華.M S P 430單片機(jī)入門與提高:全國(guó)大學(xué)生電子設(shè)計(jì)競(jìng)賽實(shí)訓(xùn)教程[M].武漢:華中科技大學(xué)出版社,2013.
責(zé)任編輯:張隆輝
T N 871
A
1672-2094(2017)04-0151-03
2017-05-14
劉 宸(1982-),男,四川射洪人,四川職業(yè)技術(shù)學(xué)院講師,碩士.研究方向:應(yīng)用電子技術(shù).