若要使用開發板上面的四個sw按鍵來做計數輸入,就需要知道一共按了幾下按鍵。
在這種情況下不能像以前設計電路中,簡單地使用輸入時鐘的上公升沿來檢測按鍵是否按
下。因為,如果分頻以後的時鐘頻率是10hz,按鍵一下按了1 秒鐘,那麼如果簡單地
以時鐘的上公升沿來檢測按鍵,程式就會認為實際一共按了十下按鍵。
我們經常使用的鍵盤也存在這種情況,這裡就需要一部分電路來防止上面情況的出
現。如果要防抖動,就不能用時鐘去檢測按鍵的按下狀態,而要去檢測按鍵按下或者抬
起的邊沿。例如按鍵按下的時候就檢測與按鍵連線的fpga 管腳的下降沿,按鍵鬆開
的時候就檢測與按鍵連線的fpga 管腳的上公升沿。這樣就可以不用理會按鍵按下的時
間長度,根據按鍵按下或者抬起的次數來評定計數。
本次實驗設計乙個防抖動電路,用來檢測按鍵的輸入。設定乙個計數器,初始數值
為零。用防抖動檢測電路來檢測sw按鍵的輸入,每檢測到一次按鍵的按下或者抬起,
計數器的數值加一。在數碼管顯示計數器的數值。
module seg(clk,rst_n,data_in,data_out,data_en);input clk,rst_n ;
input [3 :0 ] data_in ;
output [7 :0 ] data_out ;
output [3 :0 ] data_en ;
reg [7 :0 ] data_out ;
assign data_en = 4'b1111 ;
always @ ( posedge clk or negedge rst_n )
if( !rst_n )
data_out <= 8'b0000_0000 ;
else
begin
case( data_in )
4'b0000: data_out <= 8'b1111_1100 ;
4'b0000: data_out <= 8'b0110_0000 ;
4'b0000: data_out <= 8'b1101_1010 ;
4'b0000: data_out <= 8'b1111_0010 ;
4'b0000: data_out <= 8'b0110_0110 ;
4'b0000: data_out <= 8'b1011_0110 ;
4'b0000: data_out <= 8'b1011_1110 ;
4'b0000: data_out <= 8'b1110_0000 ;
4'b0000: data_out <= 8'b1111_1110 ;
4'b0000: data_out <= 8'b1111_0110 ;
endcase
end
endmodule
module counter(clk,
rst_n,
data_in,
data_out
);input clk,rst_n ;
input data_in ;
output [3 :0 ] data_out ;
reg [3 :0 ] data_out ;
always @ ( posedge clk or negedge rst_n )
if( !rst_n )
data_out <= 4'b0000 ;
else
begin
if( 1'b1 == data_in )
begin
if( 4'b1001 <= data_out )
data_out <= 4'b0000 ;
else
data_out <= data_out + 4'b0001 ;
endelse
data_out <= data_out ;
endendmodule
module debounce(clk,
rst_n,
key_i,
key_o
);input clk;
input rst_n;
input key_i;
output key_o;
reg key_o;
wire key;
wire clk_slow;
//分頻電路
reg [22:0] cnt;
reg [25:0] cnt_out;
wire key_o_reg ;
always @ ( posedge clk or negedge rst_n )
if ( !rst_n )
cnt <= 23'd0;
else
cnt <= cnt + 1'b1;
assign clk_slow = cnt[22];
//防反跳電路
reg temp_r [2:0];
reg key_r;
integer i;
always @ ( posedge clk_slow or negedge rst_n )
if ( !rst_n )
begin
for ( i = 0 ; i < 3; i = i+ 1)
temp_r[i] <= 'd0;
endelse
begin
temp_r[0] <= key_i;
temp_r[1] <= temp_r[0];
temp_r[2] <= temp_r[1];
endassign key = (~temp_r[0]) & temp_r[1] & temp_r[2];
always @ ( posedge clk or negedge rst_n )
if ( !rst_n )
key_r <= 1'b0;
else
key_r <= key;
assign key_o_reg = key & (~key_r);
/*always @ ( posedge clk or negedge rst_n )
if( !rst_n )
key_o <= 1'b0 ;
else
begin
if( cnt_out<='d33554432 )
begin
if( cnt_out=='d0 )
begin
if( key_o_reg )
begin
cnt_out <= 'd1 ;
key_o <= 1'b1 ;
endelse
begin
cnt_out <= 'd0 ;
key_o <= 1'b0 ;
endend
else
cnt_out <= cnt_out + 'd1 ;
endelse
cnt_out <= 'd0 ;
end
*/endmodule
module top_new(clk,key_i,
rst_n,
data,
en);
input clk;
input key_i;
input rst_n;
output [7:0] data;
output [3:0] en;
wire [3:0] xlxn_1;
wire xlxn_3;
counter xlxi_1 (.clk(clk),
.data_in(xlxn_3),
.rst_n(rst_n),
.data_out(xlxn_1[3:0]));
debounce xlxi_2 (.clk(clk),
.key_i(key_i),
.rst_n(rst_n),
.key_o(xlxn_3));
seg xlxi_3 (.clk(clk),
.data_in(xlxn_1[3:0]),
.rst_n(rst_n),
.data_en(en[3:0]),
.data_out(data[7:0]));
endmodule
按鍵防抖動程式
第乙個防抖動程式 key2.v module key2 input clk,rst,key,output led 分頻器 開始 reg 17 0 cout always posedge clk if rst cout 0 else cout cout 1 b1 wire clk 5ms cout 相...
FPGA按鍵防抖動程式 Verilog
module fangdoudong clk,reset,key in 1,key in 2,key in 3,led 1,led 2,led 3 input clk 50mhz input reset 高電平有效 input key in 1,key in 2,key in 3 開關key in ...
使用定時器實現按鍵防抖動
button.c include include include include include include include include include include include include static struct class sixthdrv class static str...