實驗六 按鍵防抖動實驗

2021-08-25 06:54:35 字數 4332 閱讀 9008

若要使用開發板上面的四個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...