按鍵的去抖,是指按鍵在閉合或者鬆開的瞬間伴隨一連串的抖動,這樣的抖動將直接影響設計系統的穩定性,降低相應的靈敏度。因此,必須對抖動進行處理,及消除抖動的影響。在實際工程中有很多消抖的方案,如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後檢測按鍵狀態,如果按鍵狀態為低電平,說明按鍵按下,輸出低電...