FPGA按鍵消抖

2021-10-13 18:33:38 字數 3777 閱讀 6752

fpga按鍵消抖
key_s0:判斷按鍵是否按下,如果是,轉移到狀態 key_s1;

key_s1:10ms 後再次判斷按鍵是否按下,如果是,轉移狀態到 key_s2,否則繼續回到 key_s0;

key_s2:判斷按鍵是否抬起,如果是,轉移狀態到 key_s3

key_s1:10ms 後再次判斷按鍵是否抬起,如果是,轉移狀態到 key_s0,否則繼續回到 key_s2;

將按鍵按下到鬆開,將整個過程,分成了四個部分,也就是四個狀態,狀態機就是狀態轉化。

由於按鍵經常用,消抖也是個非常重要的部分,為消抖寫個模組,方便後面用。我們起個名字 super_key.

首先是模組的輸入輸出,

時鐘輸入,按鍵輸出,按鍵狀態輸出

module super_key(

input clk_i,

input key_i,

output key_cap

);(mark_debug = 「true」)這個東西,標識出要探測的訊號。觀察波形才會用(到時候再補)。

比如(mark_debug = 「true」) reg [1:0] key_s = 2』b0;

(mark_debug = 「true」) reg [1:0] key_s_r = 2』b0;

(mark_debug = 「true」) wire en_10ms ;

引數別名

parameter clk_freq = 100000000;

parameter cnt_10ms = (clk_freq/100 - 1』b1);

parameter key_s0 = 2』d0;

parameter key_s1 = 2』d1;

parameter key_s2 = 2』d2;

parameter key_s3 = 2』d3;

用來計數 reg [24:0] cnt10ms = 25』d0;

連續賦值

assign en_10ms = (cnt10ms == cnt_10ms);

assign key_cap = (key_skey_s2)&&(key_s_rkey_s1); (下面講)

由原理圖知道 按鍵按下為,低電平。

**實現

從上面我們就可以看出來,我們沒10ms判斷一下按鍵狀態,從而實現按鍵狀態改變。

第一部分計時10ms,第二部分 狀態改變

第一部分 十毫秒延時

always @(posedge clk_i)begin

if(cnt10ms < cnt_10ms)

cnt10ms <= cnt10ms + 1』b1;

else

cnt10ms <= 25』d0;

end非常簡單 時鐘上公升沿 cnt10ms ++,擠滿置0。

看上面連續賦值語句 10ms計時到的時候,en_10ms會置1,

第二部分 狀態改變

always @(posedge clk_i)begin

key_s_r <= key_s;

endalways @(posedge clk_i)begin

if(en_10ms)begin

case(key_s)

key_s0:begin

if(!key_i)

key_s <= key_s1;

endkey_s1:begin

if(!key_i)

key_s <= key_s2;

else

key_s <= key_s0;

endkey_s2:begin

if(key_i)

key_s <= key_s3;

endkey_s3:begin

if(key_i)

key_s <= key_s0;

else

key_s <= key_s2;

endendcase

endend

10ms捕獲一次按鍵狀態,滿足對應條件,進入下乙個狀態,否則回到最初狀態。

總體** :

`timescale 1ns / 1ps

module super_key(

input clk_i,

input key_i,

output key_cap

);parameter clk_freq = 100000000;

parameter cnt_10ms = (clk_freq/100 - 1』b1);

parameter key_s0 = 2』d0;

parameter key_s1 = 2』d1;

parameter key_s2 = 2』d2;

parameter key_s3 = 2』d3;

reg [24:0] cnt10ms = 25』d0;

(mark_debug = 「true」) reg [1:0] key_s = 2』b0;

(mark_debug = 「true」) reg [1:0] key_s_r = 2』b0;

(mark_debug = 「true」) wire en_10ms ;

assign en_10ms = (cnt10ms == cnt_10ms);

assign key_cap = (key_skey_s2)&&(key_s_rkey_s1);

always @(posedge clk_i)begin

if(cnt10ms < cnt_10ms)

cnt10ms <= cnt10ms + 1』b1;

else

cnt10ms <= 25』d0;

endalways @(posedge clk_i)begin

key_s_r <= key_s;

endalways @(posedge clk_i)begin

if(en_10ms)begin

case(key_s)

key_s0:begin

if(!key_i)

key_s <= key_s1;

endkey_s1:begin

if(!key_i)

key_s <= key_s2;

else

key_s <= key_s0;

endkey_s2:begin

if(key_i)

key_s <= key_s3;

endkey_s3:begin

if(key_i)

key_s <= key_s0;

else

key_s <= key_s2;

endendcase

endend

endmodule

疑問 1:

always @(posedge clk_i)begin

key_s_r <= key_s;

end有什麼用

疑問2:

assign key_cap = (key_skey_s2)&&(key_s_rkey_s1); (下面講)

always @(posedge clk_i)begin

key_s_r <= key_s;

endkey_s_r <= key_s; ,則(key_skey_s2)&&(key_s_rkey_s1) 必為0

疑問1解答:

我們是當按鍵按下到松下,記一次按鍵按下事件。

疑問2解答:

由問題1我們知道按鍵按下事件 是按鍵從按下到鬆開整個過程,

由**我們可以發現key_s是每十毫秒改變一次,key_s發生,是在下個時鐘上公升沿才將值賦給key_s_r。

也就是在莫乙個時刻 key_s是現態 key_s_r是上乙個狀態。

FPGA 按鍵消抖

今天簡單的說說按鍵消抖,原理特別好理解,其實就是延時,做一定時間的延時後取值一次,就能夠得到特定的消抖後的狀態了。為什麼要消抖?見圖 我們可以看到,但按鍵按下的那一刻,存在一段時間的抖動,同時在釋放按鍵的一段時間裡也是存在抖動的,這就可能導致狀態在識別的時候可能檢測為多次的按鍵,因為執行過程中普通的...

FPGA之按鍵消抖

按鍵是一種常用的人機互動輸入介面,對於機械按鍵來說,在按下或彈起的時候,按鍵輸入值往往伴隨著輸入抖動。消除抖動的方式有很多種,以下是用fpga實現按鍵消抖。實現原理 當檢測到按鍵按下 一般按下為低電平 時開始計時 用計數器實現 大概10ms後檢測按鍵狀態,如果按鍵狀態為低電平,說明按鍵按下,輸出低電...

2014 3 12 FPGA學習 按鍵消抖

生性愚鈍,現在才終於明白fpga的按鍵消抖原理。先貼一段別人的 dule key debounce sys clk sys rstn key in led out 輸入輸出訊號 input sys clk input sys rstn input key in output led out 暫存器定...