電商網(wǎng)站建站開發(fā)語言seo快速建站
目錄
1.原理
2.代碼
2.1 key_filter.v
2.2 tb_key_filter.v
1.原理
按鍵分為自鎖式按鍵和機械按鍵,圖左邊為自鎖式按鍵
上圖為RS觸發(fā)器硬件消抖,當按鍵的個數(shù)比較多時常常使用軟件消抖。硬件消抖會使用額外的器件占用電路板上的空間。
思路就是使用延時程序去掉抖動的部分,抖動就是不規(guī)則的高低電平變化。
只要在20ms之內(nèi)沒有抖動的產(chǎn)生,就可以認為按鍵的可用的。計數(shù)器的作用就是當檢測道低電平時就開始計數(shù),當檢測到高電平時就清零。
因為50MHZ的時鐘,周期為20ns,要計滿20ms,20ms=20000_000ns,則計數(shù)器要計數(shù)20000_000/20=1000_000個時鐘周期,所以計數(shù)器的值是從0-999_999。
出現(xiàn)了一個問題,若穩(wěn)定的時間足夠長,在穩(wěn)定期間就會出現(xiàn)多次清零,多個最大值,多個脈沖信號,這不是我們想要的結(jié)果。為此對波形圖做修改。
此時的原理就是當計數(shù)道最大值時計數(shù)器不清零,直到下一個按鍵輸入檢測到為高電平再清零。
但此時輸出信號就不再是一個脈沖信號了,而是一個長長的高電平。因此再次對波形圖做修改。
當計數(shù)到999_999-1時,就把輸出拉高一個時鐘周期,然后清零。
以上這張圖的tb_cnt是為了仿真的。19-49(前抖動),149-199賦值隨機數(shù)模擬抖動(后抖動),0-19,199-249賦值為高電平模仿按鍵未被按下,其余時間賦值為0模仿按鍵按下。
2.代碼
2.1 key_filter.v
module key_filter
#(parameter CNT_MAX=20'd999_999
)
(input wire sys_clk ,input wire sys_rst_n ,input wire key_in ,output reg key_flag
);reg [19:0] cnt_20ms ;always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)cnt_20ms<=20'd0;else if(key_in==1'b1)cnt_20ms<=20'd0;else if(cnt_20ms==CNT_MAX)cnt_20ms<=CNT_MAX;elsecnt_20ms<=cnt_20ms+20'd1;always @(posedge sys_clk or negedge sys_rst_n)if (sys_rst_n==1'b0)key_flag<=1'b0;else if(cnt_20ms==CNT_MAX-20'd1)key_flag<=1'b1;elsekey_flag<=1'b0;endmodule
2.2 tb_key_filter.v
`timescale 1ns/1ns
module tb_key_filter();reg sys_clk ;
reg sys_rst_n;
reg key_in ;
reg [7:0] tb_cnt ;//使用計數(shù)器進行一個周期的計數(shù),模擬一次按鍵按下,計數(shù)的最大值暫定為250次(8位)wire key_flag ;initialbeginsys_clk=1'b1;sys_rst_n<=1'b0;#20sys_rst_n<=1'b1;endalways #10 sys_clk=~sys_clk;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==1'b0)tb_cnt<=8'd0;else if(tb_cnt==8'd249)tb_cnt<=8'd0;elsetb_cnt<=tb_cnt+8'd1;//模擬按鍵過程,檢測到低電平開始計數(shù),檢測到高電平清0
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n==1'b0)key_in<=1'b1;else if(((tb_cnt>=8'd19)&&(tb_cnt<=8'd49))||((tb_cnt>=8'd149)&&(tb_cnt<=8'd199))) //模仿抖動key_in<={$random}%2;else if((tb_cnt<8'd19)||(tb_cnt>8'd199))//模仿按鍵未被按下key_in<=1'b1;else key_in<=1'b0; //模仿穩(wěn)定時候key_filter
#(.CNT_MAX(20'd24) //相當于計數(shù)25
)
tb_key_filter
(. sys_clk (sys_clk),. sys_rst_n (sys_rst_n),. key_in (key_in) ,. key_flag (key_flag)
);endmodule
計數(shù)器最大計數(shù)到249,共計數(shù)250正確。
0-19 key_in是高電平
計數(shù)器計數(shù)19-49模擬抖動
49-149模擬按鍵按下穩(wěn)定狀態(tài)
觀察標志信號,確在計數(shù)穩(wěn)定25次之后,也就是計數(shù)第24的時候拉高標志信號一個時鐘周期