C51按鍵程序編寫的基礎
◎按鍵檢測的原理
常見的獨立按鍵,相信大家并不陌生,各種常見的開發(fā)板學習板上隨處可以看到他們的身影。
總共有四個引腳,一般情況下,處于同一邊的兩個引腳內部是連接在一起的,如何分辨兩個引腳是否處在同一邊呢?可以將按鍵翻轉過來,處于同一邊的兩個引腳,有一條突起的線將他們連接一起,以標示它們倆是相連的。如果無法觀察得到,用數字萬用表的二極管擋位檢測一下即可。搞清楚這點非常重要,對于我們畫PCB的時候的封裝很有益。
它們和我們的單片機系統(tǒng)的I/O口連接一般如下:
對于單片機I/O內部有上拉電阻的微控制器而言,還可以省掉外部的那個上拉電阻。簡單分析一下按鍵檢測的原理。當按鍵沒有按下的時候,單片機I/O通過上拉電阻R接到VCC,我們在程序中讀取該I/O的電平的時候,其值為1(高電平); 當按鍵S按下的時候,該I/O被短接到GND,在程序中讀取該I/O的電平的時候,其值為0(低電平) 。這樣,按鍵的按下與否,就和與該按鍵相連的I/O的電平的變化相對應起來。結論:我們在程序中通過檢測到該I/O口電平的變化與否,即可以知道按鍵是否被按下,從而做出相應的響應。一切看起來很美好,是這樣的嗎?
◎現實并非理想
在我們通過上面的按鍵檢測原理得出上述的結論的時候,其實忽略了一個重要的問題,那就是現實中按鍵按下時候的電平變化狀態(tài)。我們的結論是基于理想的情況得出來的,就如同下面這幅按鍵按下時候對應電平變化的波形圖一樣:
而實際中,由于按鍵的彈片接觸的時候,并不是一接觸就緊緊的閉合,它還存在一定的抖動,盡管這個時間非常的短暫,但是對于我們執(zhí)行時間以us為計算單位的微控制器來說,
它太漫長了。因而,實際的波形圖應該如下面這幅示意圖一樣。
這樣便存在這樣一個問題。假設我們的系統(tǒng)有這樣功能需求:在檢測到按鍵按下的時候,將某個I/O的狀態(tài)取反。由于這種抖動的存在,使得我們的微控制器誤以為是多次按鍵的按下,從而將某個I/O的狀態(tài)不斷取反,這并不是我們想要的效果,假如該I/O控制著系統(tǒng)中某個重要的執(zhí)行的部件,那結果更不是我們所期待的。于是乎有人便提出了軟件消除抖動的思想,道理很簡單:抖動的時間長度是一定的,只要我們避開這段抖動時期,檢測穩(wěn)定的時候的電平不久可以了嗎?聽起來確實不錯,而且實際應用起來效果也還可以。于是,各種各樣的書籍中,在提到按鍵檢測的時候,總也不忘說道軟件消抖。就像下面的偽代碼所描述的一樣。(假設按鍵按下時候,低電平有效)
If(0 == io_KeyEnter)
{
{
}
}
乍看上去,確實挺不錯,實際中呢?在實際的系統(tǒng)中,一般是不允許這么樣做的。為什么呢?首先,這里的Delayms(20) , 讓微控制器在這里白白等待了20 ms 的時間,啥也沒干,考慮我在《學會釋放CPU》一章中所提及的幾點,這是不可取的。其次while(0 == io_KeyEnter) ;更是程序設計中的大忌(極少的特殊情況例外)。任何非極端情況下,都不要使用這樣語句來堵塞微控制器的執(zhí)行進程。原本是等待按鍵釋放,結果CPU就一直死死的盯住該按鍵,其它事情都不管了,那其它事情不干了嗎?你同意別人可不會同意?所以合理的分配好微控制的處理時間,是編寫按鍵程序的基礎。
◎消除抖動有必要嗎?
的確,軟件上的消抖確實可以保證按鍵的有效檢測。但是,這種消抖確實有必要嗎?有人提出了這樣的疑問。抖動是按鍵按下的過程中產生的,如果按鍵沒有按下,抖動會產生嗎?如果沒有按鍵按下,抖動也會在I/O上出現,我會立刻把這個微控制器錘了,永遠不用這樣一款微控制器。所以抖動的出現即意味著按鍵已經按下,盡管這個電平還沒有穩(wěn)定。所以只要我們檢測到按鍵按下,即可以返回鍵值,問題的關鍵是,在你執(zhí)行完其它任務的時候,再次執(zhí)行我們的按鍵任務的時候,抖動過程還沒有結束,這樣便有可能造成重復檢測。所以,如何在返回鍵值后,避免重復檢測,或者在按鍵一按下就執(zhí)行功能函數,當功能函數的執(zhí)行時間小于抖動時間時候,如何避免再次執(zhí)行功能函數,就成為我們要考慮的問題了。這是一個仁者見仁,智者見智的問題,就留給大家去思考吧。所以消除抖動的目的是:防止按鍵一次按下,多次響應。
評論