資源描述:
《鍵盤掃描去抖方法》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、實現(xiàn)簡潔高效的鍵盤處理對于提高單片機系統(tǒng)的可靠性及速度有重要意義。鍵盤處理的重要環(huán)節(jié)是掃描和去抖,不少書籍在介紹這些內(nèi)容時往往只介紹查詢和循環(huán)延遲的方法,這使初學(xué)者比較容易理解,但在實際中通常不會使用這些方法,因為那樣的話效率太低了。這里我們介紹一種采用定時掃描和計數(shù)去抖的鍵盤處理方法,它不僅使程序非常簡單高效,而且便于靈活擴展實現(xiàn)處理更復(fù)雜的鍵盤要求。本文先介紹它的基本算法。算法流程圖圖1位該算法的流程圖,它用到下面的變量和常數(shù)。變量KscnaBuf:鍵盤掃描碼緩存KScan:鍵盤掃描碼KCount:去抖計數(shù)器KReady:按鍵有效標(biāo)志常量KD_val:去抖計數(shù)長
2、度算法的基本過程如下:CPU以一定時間間隔周期地執(zhí)行此鍵盤掃描處理程序。先是對鍵盤作掃描,獲得反映鍵盤狀態(tài)的鍵盤掃描碼;然后對掃描碼進行前后對比和定時計數(shù),實現(xiàn)去抖;去抖后置位KReady標(biāo)志,通知鍵盤分析程序已檢測到有效按鍵。關(guān)于鍵盤掃描碼鍵盤掃描碼反映讀取鍵盤時刻的鍵盤動作狀態(tài)。對鍵盤掃描碼的基本要求是它要能對每一個單鍵作唯一編碼,如果要使用多鍵組合則要能對每一種組合進行唯一編碼。通常能做到對任意單鍵或雙鍵作唯一編碼即能滿足大多數(shù)場合的要求。具體鍵盤掃描碼的編碼方法隨采用電路的不同而不同,這里以圖2中的4X4鍵盤為例說明。在該電路中,D4–D7是輸出,D0–D3
3、是輸入。在讀取鍵盤時程序分別將D4,D5,D6和D7單獨地置成低電平,然后依次讀取D0–D3,即可獲得所有按鍵的狀態(tài)。我們可以將D0–D3與D4–D7合在一起,作為按鍵的編碼。例如,當(dāng)A鍵按下時,得到的編碼是10111110;當(dāng)B鍵按下時,得到的編碼是01110111。為了反映整個鍵盤的狀態(tài),可以將D0–D3不全為1的編碼作邏輯與,其結(jié)果作為鍵盤掃描碼??梢则炞C,這樣設(shè)計的掃描碼能夠唯一地標(biāo)識任意單鍵或雙鍵的動作狀態(tài)。去抖的實現(xiàn)我們知道,當(dāng)一個按鍵按下和釋放時,對應(yīng)信號線電平的變化有一個不穩(wěn)定期,即所謂“抖動”,這是因為多數(shù)開關(guān)的閉合和斷開都有一個過程,并不是即刻實
4、現(xiàn)的。在讀取鍵盤狀態(tài)是必須避開這個不穩(wěn)定期,以免造誤判,這樣一個做法叫做“去抖”。圖3是一按鍵的動作波形,箭頭表示定時掃描時讀取鍵盤的時刻。可以看出,如果當(dāng)在一段時間內(nèi)都連續(xù)多次讀到同一個非空(即有鍵按下)的掃描碼,我們可以認(rèn)為這時按鍵已處于穩(wěn)定狀態(tài),這時得到的掃描碼就代表了一個鍵盤動作,抖動的影響已經(jīng)被剔除。按照這個想法,我們只需設(shè)置一計數(shù)器,當(dāng)每次讀到的非空掃描碼與上一次的相同,就將計數(shù)器加1;而當(dāng)一旦讀到不同的掃描碼或空碼則立即將計數(shù)器清0。如果計數(shù)器的值達到某預(yù)定值N時,則表示連續(xù)N次讀到同一掃描碼,于是可認(rèn)為已經(jīng)讀到了有效的按鍵。設(shè)鍵盤掃描的間隔是T,則去
5、抖的時間就是N*T。在實際中可以根據(jù)按鍵的特性選取適當(dāng)?shù)腘和T值,以達到可靠的去抖效果。應(yīng)用說明及示例鍵盤掃描程序通常用定時中斷周期地啟動執(zhí)行。不過一般不宜將整個鍵盤掃描程序全部放在中斷響應(yīng)程序里,因為那樣會降低系統(tǒng)對其他中斷響應(yīng)的性能。通常可以把它放在程序的主循環(huán)里(這里只是針對前后臺系統(tǒng)討論,若是多任務(wù)系統(tǒng)可以將其設(shè)計成一個任務(wù)),由定時中斷程序通過一個標(biāo)志周期地啟動其執(zhí)行。當(dāng)然,如果系統(tǒng)對中斷響應(yīng)性能要求不高,也可以將整個鍵盤掃描程序放在中斷響應(yīng)程序里。在系統(tǒng)啟動時,需要對鍵盤掃描程序作初始化,即將KReady和KDcnt清0。掃描獲得的有效鍵盤動作通過變量K
6、Scan和標(biāo)志KReady傳遞給鍵盤分析執(zhí)行程序。下面應(yīng)用示例程序。注意這不是完整的程序,若要直接使用則需要加上變量和常量定義,并根據(jù)所用的編譯器寫中斷響應(yīng)函數(shù)。//--中斷程序……DoKeyScan=1;……//--鍵盤掃描及去抖程序voidKeyScan(void){//--掃描鍵盤,獲得掃描碼……//--去抖處理if(KScanBuf==NoKey)
7、
8、(KScanBuf!=KScan)){KScan=KScanBuf;KCount=0;}else{if(KCount==KD_val)return;//避免重復(fù)KCount++;If(KCount==KD_va
9、l)KReady=1;}}//--主程序intmain(){//--初始化KReady=0;KCount=0;……while(1){……if(DoKeyScan==1){//--作鍵盤掃描去抖DoKeyScan=0;KeyScan();}if(KReady==1){//--作鍵盤分析處理KReady=0;……}……}}該算法稍作修改,還可以靈活實現(xiàn)其他特殊的鍵盤要求,如重復(fù)、長按、釋放時動作等,對此我們將另覓篇幅介紹。(2008.1.15)