判斷按鍵值 FPGA入門系列10按鍵消抖

2021-10-14 16:19:25 字數 3551 閱讀 2368

文章

簡介

本系列文章主要針對fpga初學者編寫,包括fpga的模組書寫、基礎語法、狀態機、ram、uart、spi、vga、以及功能驗證等。將每乙個知識點作為乙個章節進行講解,旨在更快速的提公升初學者在fpga開發方面的能力,每乙個章節中都有針對性的**書寫以及**的講解,可作為讀者參考。

第十一章:按鍵消抖

之前的章節講解了呼吸燈、狀態機、top-down 設計,本章將這些知識點進行串聯起來,設計要求如下:

①在開發板上完成自動售貨機的實驗,投幣的動作通過按鍵實現,當按1次按鍵(按下到抬起算一次),算作投幣1次; 

②按下一次按鍵,led 燈亮乙個,按下兩次按鍵後,led 燈亮兩個,當按三次按鍵後,用呼吸燈充當出可樂的效果,呼吸燈持續十秒後熄滅,狀態回到初始狀態。 

根據上面的要求,先畫出對應的狀態轉移圖如圖 1 所示。

根據圖 1 所示的狀態轉移圖可以描述出該狀態機,idle 狀態、one 狀 態、two 狀態、three 狀態的跳轉條件均是 key(按鍵),three 狀態進入 idle 狀態的條件為十秒鐘結束。在 idle 狀態 led 燈全滅,one 狀態 led 燈亮乙個, two 狀態 led 燈亮兩個,three 狀態 led 燈進入呼吸狀態。

一般情況下,我們從按下按鍵到鬆開基本需要大於幾十毫秒的時間,系統時鐘的週期處於納秒級,因此我們按下一次按鍵會被大於十萬個時鐘的上公升沿採集到,然而我們希望的是按下一次按鍵只被一次上公升沿採集到,不然會被認為按了多次按鍵,所以我們需要對我們的按鍵進行處理。假設按鍵在沒被按下時為高電平,被按下時處於低電平,如圖 2 所示的波形圖。

由圖 2 分析可知在 key 被按下時有且僅有乙個 key 的上公升沿和乙個 key 的下降沿,我們可以通過檢測 key 的上公升沿或者下降沿來確定按鍵被按下一次, 這就涉及到邊緣檢測,具體方法如圖 3 所示,可以用 clk 的上公升沿將 key 延時一 個週期產生 key_reg,通過 key 和 key_reg 的值同時判斷 key 的上公升沿或下降 沿。由圖 3 可知,當用 clk 的上公升沿檢測到 key 等於 1 的同時 key_reg 等於 0, 此時則為 key 的上公升沿,若 key 等於 0 的同時 key_reg 等於 1 則為 key 的下降 沿。

由圖 3 可知根據 key 的上公升沿或下降沿可確定按鍵按了一次,然而事實卻不允許我們這麼做。圖 4 給出了乙個按鍵的模型,當不按下按鍵 s 時,a、b 兩點 是斷開的,按下按鍵 s 時線路才接通,然而當按下按鍵時,會存在物理上的抖動現象,此時 a、b 兩點會在斷開和接通之間反覆的一段時間,就會出現圖 5 所 示的抖動、穩定的波形。

圖 5 所示前抖動為按下時產生的抖動,後抖動為按鍵鬆開時造成的抖動, 前、後抖動持續時間一般均為 5~10ms,在有抖動的情況下,key 會被 clk 上公升沿採集到很多的上公升沿和下降沿,因此用 key 的上公升沿和下降沿判斷按鍵一次就不成立了,我們需要尋找新的方法。

我們知道按鍵被按下時 key 值為低電平(0),在抖動期間 key 既有高電平也有低電平,我們可以使用 clk 的上公升沿計算 key 連續為低電平的時間,期間當檢 測到 key 為高電平時,則從頭開始計數,當計數超過 5~10ms 時,我們可以認定按鍵有被按下的時候,此時我們可以產生乙個 clk 週期為高電平的標誌,當該標 志位高電平認為有一次按鍵即可,具體波形如圖 6 所示。

此處我們認為 key 值有連續性的 5ms 時為按鍵被按下,時鐘週期為 50mhz, 即 20ns,可以算出 5ms 佔 250000 個 clk 週期,也就是說 cnt 從 0 計數到 249999 為 5ms,當 cnt 等於 249999 時可以將 po_key_flag 拉高乙個週期,由於按鍵時間長短無法確定,因此 cnt 有可能多次達到 249999 這個值,會造成 po_key_flag 多次被拉高,這樣又會出現按下一次鍵被當成按下多次,所以在 圖 6 **現了 cnt_flag 變數,在遇到 cnt 等於 249999 時,cnt_flag 就會被置高,直到遇到 key 等於高電平時才會被拉低,這樣我們就可以將第乙個 cnt 等 於 249999 和後面的區分開,那麼我們也可以用 cnt 和 cnt_flag 共同控制在一次按鍵中,保證 po_key_flag 有且僅有乙個時鐘週期的高電平。根據波形圖可得到如下所示的**。

**示例:

①第 17 行的 always 塊實現了乙個計數器,當 key 鍵按下(值為 0)的時候開始計數,當檢測到按鍵鬆開(值為 1)的時候計數器歸零,這樣在抖動時候,該計數器會出現計數、歸零迴圈的乙個過程,直到 key 值一直 為 0,即按鍵持續被按下並且抖動過程結束,計數器才會持續計數到 5ms; 

②第 26 行的 always 塊產生乙個標誌,當檢測到 cnt 第一次等於 5ms 的時候,該標誌則被置為高電平,這樣就可以將 cnt 第一次等於 5ms 和之後 的 cnt 等於 5ms 區分開,直到 key 鬆開(值為 1)時,該標誌才被置為低電平; 

③第 34 行的 always 塊實現產生整個按鍵過程中的乙個時鐘週期高電平的標誌,當 cnt 計數到 5ms 時,為了確保只有一次的 po_key_flag 有效, 因此此處條件中不僅需要 cnt==5ms,而且需要 cnt_flag==0。至此,實現了按鍵的消抖處理,在此基礎上就可以很好地實現最初的要求了。

在第十二章中將對verilog hdl 中數碼管進行講解。

往期回顧

fpga入門系列1--模組書寫&電路綜合

fpga入門系列2--**驗證

fpga入門系列3--wire與reg

fpga入門系列4--賦值語句

fpga入門系列5--運算符號

fpga入門系列6--判斷語句

fpga入門系列7--時鐘分頻

fpga入門系列8--top_down設計

fpga入門系列9--狀態機及do檔案

未完待續

STM32F103入門 10 按鍵實驗(上)

之前的點亮小燈實驗用到了gpio的輸出模式,但是對於輸入模式沒有用到,這次小r給小夥伴們介紹gpio的其中一種輸入模式 上拉輸入。按鍵出現在很多的應用場景,按鍵處理更是一門學問。因此,小r給小夥伴們介紹gpio的上拉輸入模式並簡單應用於按鍵實驗中,通過判斷按鍵的狀態來控制led燈的亮滅情況。首先,需...

STM32F103入門 10 按鍵實驗(上)

之前的點亮小燈實驗用到了gpio的輸出模式,但是對於輸入模式沒有用到,這次小r給小夥伴們介紹gpio的其中一種輸入模式 上拉輸入。按鍵出現在很多的應用場景,按鍵處理更是一門學問。因此,小r給小夥伴們介紹gpio的上拉輸入模式並簡單應用於按鍵實驗中,通過判斷按鍵的狀態來控制led燈的亮滅情況。首先,需...

學FPGA如何少走10年彎路?入門很重要!

與典型的微控制器相比,現場可程式設計門陣列fpga是一種能夠提供更強效能和靈活性的器件,本文通過解答幾個有關fpga的常見問題 什麼是fpga 為什麼我會需要fpga 如何為fpga程式設計 為開發者提供fpga入門所需的基本概念和知識。如果您是二元思維的人,那麼不要錯過第1到4部分內容。在這篇部落...