基于FPGA的邊緣檢測工程按鍵部分詳細解析
本文為明德揚原創文章,轉載請注明出處!作者:小黑同學
1.1 硬件電路
明德揚采用MP801開發板來進行邊緣檢測項目,在開發板中按鍵的實際位置如下圖所示:
明德揚MP801開發板采用4個獨立按鍵加一個復位按鍵,其中最左邊為復位按鍵,并且采用上拉的連接方法,默認為1,當按鍵按下時,按鍵的電平被拉低。按鍵的電路原理圖如下所示:
1.2按鍵原理
MP801開發板上的按鍵為機械式開關結構,此機械式開關的是具有彈性的,因為其核心部件為彈性金屬簧片,那么在開啟或者閉合的瞬間會在接觸點出現來回彈跳的現象,即我們說的按鍵抖動。當然這種情況并不是只在MP801開發板上出現,現階段下絕大多數的按鍵都是機械式開關結構,這是無法避免的問題。
雖然只是進行了一次按鍵,其實在按鍵信號穩定的前后出現了多個脈沖,實際產生的波形如下圖所示:
在按鍵閉合和斷開的瞬間,我們其實只需要一組穩定的上升沿和下降沿,但是實際情況卻產生了若干個沿。因此在實際的電路中,如果將這樣的信號直接傳送給微處理器掃描采集的話,那就存在把抖動信號當做按鍵信號的可能,這樣雖然只按了一次按鍵,但是微處理器卻認為按了多次按鍵。為了可以達到按一次按鍵就可以得到一次識別的效果,就需要對按鍵進行消抖處理,消除按下按鍵時不穩定、隨機的抖動電壓信號。機械式按鍵的抖動次數、抖動時間、抖動波形都是隨機的,不同類型的按鍵的最長抖動時間也不同,抖動時間的長短和按鍵的機械特性有關,一般為5到10ms,但有些按鍵的抖動時間可達到 20 ms甚至更長。因此,具體設計中要具體分析,根據實際情況來調整設計。
1.3 按鍵捕捉
有些同學看到按鍵消抖處理,就理所應當以為是將按鍵按下這一活動的抖動部分進行消除,但其實按鍵的消抖只是一種比較正式的說法,其本質上是在抖動的波形中,捕捉到比較穩定的電壓。
我們通過實際情況來學習下。一般按鍵都是低電平有效,通常情況下按鍵信號為高電平,當主動按下按鍵時會變成低電平,這是按鍵的基本電平情況。前面我們有說到,在按下的瞬間,穩定狀態的信號前后都會產生抖動,這時即使按鍵信號等于0也無法表示按鍵被按下。
為了解決這一問題,我們對此進行了思考,不論信號為抖動信號還是正常信號,都對此進行采集,并對其進行監控,如果信號變0,就可以暫時的判斷為進行了按下按鍵操作。接著我們來判斷持續時間,當此操作只持續了一瞬間,信號就變回了1,那么可以判斷為按鍵抖動;反之如果信號為0持續了一段時間并且趨于穩定,那么就可以判斷此操作為按下按鍵。明德揚管這種行為叫做按鍵捕捉,在按鍵信號中捕捉到持續一段時間的低電平信號,判斷為按下按鍵的有效操作。關于持續時間的判斷,明德揚使用的MP801開發板抖動時間比較短,低電平信號持續10ms以上就可以判斷為按下按鍵的行為成立。
如下圖所示,按鍵持續為高電平,當按下按鍵的時候會變為低電平,但是在此前后都會產生一段高高低低的抖動信號。按鍵捕捉的方法就是持續的檢測信號的進度,比如到第一個低電平產生時,開始計時,假設第一個出現的低電平持續時間為6ms,不滿足按鍵按下標準;第二個低電平信號出現持續時間為8ms,不滿足按鍵按下標準;到第四個低電平信號,持續了10ms以上,滿足按下按鍵標準,即可判斷這里有一次的按下按鍵操作;接著第五個低電平信號,持續時間為6ms,不滿足按下按鍵標準。這種方法,就可以幫助我們很好的確判斷有效按鍵信號。
我們將捕捉到的持續10ms以上低電平狀態的信號提取出來,就是表示按下按鍵操作的信號。在這里,明德揚會選擇產生一個有效指示信號key_vld來表示按鍵的狀態。此信號初始狀態為低電平,當捕捉到按鍵按下操作時,信號key_vld會變為高電平,持續一個時鐘周期,然后重新變為低電平。這時我們只要通過判斷key_vld信號的狀態,如有沒有變為高電平、出現了幾個高電平,就可以判斷按鍵是否按下以及按下幾次按鍵。這里需要注意,key_vld信號不是代表按鍵的按下的低電平信號,而是已經完成了按鍵捕捉的環節,對捕捉到的成功按下按鍵結果的一個表現。持續一個時鐘周期也并不是說按鍵信號持續了一個時鐘周期,而是向大家更加清晰的表示,這里進行了按下按鍵操作。
這里可以理解為,當捕捉到一個持續10ms以上的低電平信號,信號key_vld會舉手示意一下,再次捕捉到下一個時,信號key_vld會再次舉手示意一下。信號key_vld就如它的類型一樣,為有效表示信號,只是表示按下按鍵的有效操作,不做其他。
如下圖所示,我們增加了一個key_vld信號,此信號在這段時間內拉高了一個時鐘周期,這就可以判斷按鍵按下了一次。
1.4 按鍵消抖的實現
前面有提到按鍵消抖并不是消除抖動,而是在有抖動的基礎上進行一定的操作從而更加準確的判斷按鍵操作的有效性,實現按鍵消抖有硬件方法和軟件方法。
硬件消抖的原理很簡單,就是在按鍵上并聯一個電容,如下圖,利用電容的充放電特性來對抖動過程中產生的電壓進行平滑處理,從而實現消抖。原理前面也有詳細的講述
但實際應用中,由于這種方式的效果不佳,會有一定的不穩定性,增加了電容后由提升了電路的復雜程度,并且硬件的增加也令成本提高,綜合考慮后,明德揚更多的是采用軟件即程序來實現消抖的。
前面我們講了捕捉到了足夠時間的信號,判斷為有效按鍵,明德揚的軟件消抖方法即使用計數器實現消抖。前面有講到,按下按鍵的操作會產生低電平,但是由于按鍵的抖動,導致并不是產生固定的一段低電平,而是在前后會有短時間的高低電平波動。那么我們就增加一個計數器,用來數低電平持續時間,當持續時間達到10ms的時候,判斷完成一次有效按鍵操作,當低電平持續時間不足10ms的時候,即判斷為按鍵抖動,不做有效判斷。
不同按鍵的抖動時間不同,這樣通過軟件實現按鍵消抖的方式,對于不同的按鍵可以設計不同的計數器計數時間,更具有穩定性,也節約了一定成本,非常建議大家使用。
1.5 按鍵采集實現
理解了按鍵工作的原理,我們來在FPGA中實現按鍵采集。
我們先將設計目標使用波形圖表示出來,如下圖所示,按鍵信號定義為key_in,持續為高電平狀態即1,變0表示按下按鍵,并且按下按鍵的時間是不確定的;由于按鍵信號key_in屬于異步信號,必須寄存兩拍,第一拍key_in_ff0將信號同步化,第二拍key_in_ff1減少亞穩態帶來的影響。當信號key_in_ff1變0時,計數器開始計數,計數器數夠10ms表示按下按鍵;增加一個信號flag初始狀態為0,當計數器數夠10ms時信號變1,當key_in_ff0結束變1時,flag信號變0,表示按鍵操作結束;增加一個key_vld信號,當計數器數夠10ms時拉高1個時鐘,表示成功按下一次按鍵。
根據波形圖一起來進行代碼的實現,將信號key_in異步信號同步化代碼表示如下圖所示:
接著來將計時器用代碼表示出來首先計數器的加一條件,根據波形圖可知,當key_in_ff1并且flag==0的時候,計數器加1條件成立。關于計數器數多少下,有目的可知道,當按鍵低電平持續時間足夠10ms即按鍵動作有效,因此計數器數10ms,我們使用的時鐘頻率為50Mhz,那么一個時鐘周期就是20ns,要數夠10ms,就需要500000個時鐘周期,又因為計數器是從0開始計數的,所以計數器的結束條件就是500000-1。
因此計數器的代碼表示如下所示:
接著標志信號flag,信號處于低電平狀態,當計數器數夠500000下,標志著按鍵操作成立,flag信號拉高,當key_in_ff1變1,標志著按鍵動作結束,因此flag的代碼表示如下:
當計數器數完10ms時,我們需要key_vld信號產生一個時鐘周期的高電平輸出,表示一次按鍵操作,因此當end_cnt時,信號變1,代碼表示如下:
以上就是使用按鍵采集的整個過程,其中包含了按鍵信號消抖和信號捕捉,我們再來做一個總結,當遇到有抖動產生的按鍵,就設置一個信號持續時間門檻,當信號持續時間達到這個門檻,可以判斷為有效按鍵信號,當無法達到這個門檻,則按下按鍵操作不成立。達到門檻的信號,即代表了一次按鍵操作成立,整個操作中,達到了幾次門檻,就代表按下幾次按鍵。代碼是以適配本工程硬件來寫的,但是道理都是相通的,后續讀者朋友們遇到按鍵消抖的問題可以使用這種方法解決。
更多邊緣檢測相關文件歡迎添加Q:1817866119(N老師)獲取!