FPGA設計 按鍵去抖

2021-08-29 16:32:14 字數 3965 閱讀 5521

按鍵的去抖,是指按鍵在閉合或者鬆開的瞬間伴隨一連串的抖動,這樣的抖動將直接影響設計系統的穩定性,降低相應的靈敏度。因此,必須對抖動進行處理,及消除抖動的影響。在實際工程中有很多消抖的方案,如rs觸發器消抖,電容充放電消抖,軟體消抖。本章利用fpga內部來設計消抖,即採用軟體消抖。

按鍵的機械特性,決定著按鍵的抖動時間,一般抖動時間在5ms~10ms。消抖,也意味著,每次在按鍵閉合或者鬆開期間,跳過這段抖動時間,在檢測按鍵的狀態。只要通過簡單的延時就可以實現按鍵的消抖。

本設計有兩個使用者按鍵分別為btn0和btn1。btn0用來復位,btn1用來控制四個使用者led。btn1每按一次,對應的led燈反轉一次。即檢測按鍵是否有閉合和斷開的過程,如果有,第一次則led燈點亮,第二次,則led燈熄滅。

由於按鍵固有的特性,在每次閉合和斷開時,經過抖動-穩定-抖動-穩定的過程。因此,檢測按鍵是否有按下的過程,則需要進行兩次消抖處理。通過檢測按鍵輸入的值,當檢測到btn1為低電平時,啟動計數器,做10ms延時,在檢測一次,若btn1依然為低,則說明,btn1被按下,設定按鍵按下標誌(low_flag)。在檢測btn1,若btn1為高,做10ms延遲,第二次檢測,若依然為高電平,則說明btn1已斷開,設定btn1斷開標誌(high_flag)。通過這兩個標誌位,可以判斷,btn1已經完成了一次閉合到斷開的過程,則led反轉一次。

採用狀態機實現上面的流程是非常的方便的。通過狀態機的切換,按鍵每次由閉合到斷開的過程中,分別產生low_flag和high_flag,當這兩個標誌同時為高時,led燈反轉一次。

`timescale 1ns / 1ps

//// company:

// engineer:

// // create date: 2018/10/22 21:07:25

// design name:

// module name: key_jitter

// project name:

// target devices:

// tool versions:

// description:

// // dependencies:

// // revision:

// revision 0.01 - file created

// additional comments:

// //

module key_jitter(

input clk_i,

input rst_n_i,

input key_i,

output [3:0] led_o

);localparam delay_param = 19'd499_999;

reg [3:0] led_o_r;

(*keep = "true"*) reg [18:0] div_cnt;//10毫秒去抖時間計數器

always@ (posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

div_cnt <= 19'd0;

else if (div_cnt< delay_param)

div_cnt <= div_cnt + 1'b1;

else

div_cnt <= 0;

endwire delay_10ms =(div_cnt==delay_param)?1'b1:1'b0;

//按鍵檢測

localparam detecter1 = 3'b000;

localparam detecter2 = 3'b001;

localparam detecter3 = 3'b010;

localparam detecter4 = 3'b011;

localparam led_dis = 3'b100;

reg low_flag;

reg high_flag;

reg [2:0] key_state;

always @(posedge clk_i or negedge rst_n_i)

begin

if(!rst_n_i)

begin

key_state<= detecter1;

low_flag <= 0;

high_flag <= 0;

led_o_r <=4'b1111;

endelse if(delay_10ms)

begin

case(key_state)

detecter1:

begin

if(key_i!=1'b1)

key_state <= detecter2;

else

key_state <= detecter1;

enddetecter2:

begin

if(key_i!=1'b1)

begin

low_flag <= 1'b1;

key_state <= detecter3;

endelse

begin

key_state <= detecter1;

low_flag <= low_flag;

endend

detecter3:

begin

if(key_i==1'b1)

key_state <= detecter4;

else

key_state <= detecter3;

enddetecter4:

begin

if(key_i == 1'b1)

begin

high_flag <= 1'b1;

key_state <= led_dis;

endelse

begin

high_flag <= high_flag;

key_state <= detecter3;

endend

led_dis:

begin

if(high_flag & low_flag)

begin

key_state <= detecter1;

led_o_r <= ~led_o_r;

high_flag <= 1'b0;

low_flag <= 1'b0;

endelse

begin

led_o_r <=led_o_r;

key_state <= key_state;

high_flag <= high_flag;

low_flag <= low_flag;

endend

default:

begin

key_state <= detecter1;

led_o_r <= 0;

high_flag <= 0;

low_flag <= 0;

endendcase

endelse

begin

led_o_r <=led_o_r;

key_state <= key_state;

high_flag <= high_flag;

low_flag <= low_flag;

end

endassign led_o = led_o_r;

endmodule

程式中定義了div_cnt 計數器,實現10ms消抖延時操作;

程式中定義了key_state一段式狀態機,該狀態機包括5個狀態。其中前4個位按鍵閉合與斷開檢測,在完成前4個狀態後,通過led燈的反轉來表現按鍵的閉合與斷開。

程式中定義了兩個標誌位,分別位low_flag和high_flag。low_flag表示檢測到按鍵按下,high_flag表示檢測到按鍵彈起。當兩個標誌同時為1時,表示按鍵完成一次閉合與斷開。

程式中,對狀態機做了迴圈,來回不停檢測按鍵狀態,且每次狀態的切換時間是10ms,狀態的切換時間,也是按鍵消抖的過程。

FPGA 按鍵消抖

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

FPGA按鍵消抖

fpga按鍵消抖key s0 判斷按鍵是否按下,如果是,轉移到狀態 key s1 key s1 10ms 後再次判斷按鍵是否按下,如果是,轉移狀態到 key s2,否則繼續回到 key s0 key s2 判斷按鍵是否抬起,如果是,轉移狀態到 key s3 key s1 10ms 後再次判斷按鍵是否...

FPGA之按鍵消抖

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