按键消抖的思路:设计是以按下低电平为例,当检测到按键按下时检测下降沿,启动计数器,计数10ms,再检测当前按键IO的电平,如果为低,则按键正常按下,否则可能是干扰。这里的计数时间10ms可自行修改。
//=====================================================
// Module : key_debounce.v
// Function : removimg key’s shaking when press the key
// Date : 20191121
//======================================================
module key_debounce #
(
parameter SYS_CLK = 28’d50_000_000, // system clock frequency
parameter Delay_CLK = 7’d100 // 100hz for 10ms
)
(
input Clock ,
input Rst_n ,
input key_in ,
output reg key_state
);
//======================================================
// wire define
//======================================================
localparam CLK_DEVIDE = SYS_CLK/Delay_CLK - 20’d1; // division factor
//======================================================
// wire define
//======================================================
wire negedge_key ; //
//======================================================
// reg define
//======================================================
reg key_in_d0 ;
reg key_in_d1 ;
reg clock_cnt_en ; // encable signal for system clock counter
reg [19:0] clock_cnt ; // system clock counter
//======================================================
// detect key’s negtive edge
//======================================================
assign negedge_key = ( ~key_in_d0 ) & ( key_in_d1 ) ;
always @ ( posedge Clock or negedge Rst_n )
begin
key_in_d0 <= ( Rst_n == 1’b0 ) ? 1’b0 : key_in ;
key_in_d1 <= ( Rst_n == 1’b0 ) ? 1’b0 : key_in_d0 ;
end
//======================================================
// generate encable signal for system clock counter
//======================================================
always @ ( posedge Clock or negedge Rst_n )
begin
if( Rst_n == 1’b0 )
begin
clock_cnt_en <= 1’b0;
end
else if( clock_cnt[19:0] == CLK_DEVIDE )
begin
clock_cnt_en <= 1’b0;
end
else if( negedge_key == 1’b1 )
begin
clock_cnt_en <= 1’b1;
end
else ;
end
//======================================================
// system clock counter,10ms
//======================================================
always @ ( posedge Clock or negedge Rst_n )
begin
if( Rst_n == 1’b0 )
begin
clock_cnt[19:0] <= 20’d0;
end
else if( clock_cnt_en == 1’b1 )
begin
if( clock_cnt[19:0] == CLK_DEVIDE )
begin
clock_cnt[19:0] <= 20’d0;
end
else
begin
clock_cnt[19:0] <= clock_cnt[19:0] + 20’d1;
end
end
else
begin
clock_cnt[19:0] <= 20’d0;
end
end
//======================================================
// detect key’s state again after counter == 499_999
//======================================================
always @ ( posedge Clock or negedge Rst_n )
begin
if( Rst_n == 1’b0 )
begin
key_state <= 1’b0;
end
else if( clock_cnt[19:0] == CLK_DEVIDE )
begin
if( key_in == 1’b0 )
begin
key_state <= 1’b1;
end
else
begin
key_state <= 1’b0;
end
end
else
begin
key_state <= 1’b0;
end
end
endmodule