按键消抖

 

module	Debounce #
(
parameter	KEY_WIDTH = 1 //消抖按键数量
)
(
input   					clk,		//系统时钟 12MHz
input   					rst_n,		//系统复位 低有效
input		[KEY_WIDTH-1:0]	key_n,		//按键信号输入
output	reg	[KEY_WIDTH-1:0]	key_jit,	//延时消抖输出	
output	wire[KEY_WIDTH-1:0]	key_pulse,	//消抖脉冲输出
output	reg	[KEY_WIDTH-1:0]	key_state	//消抖翻转输出
);

localparam	CNT_NUM = 18'd240000;//20ms计时

reg	[KEY_WIDTH-1:0]	key_n_r,key_n_r1,key_n_r2;//延时锁存,消除亚稳态

always@(posedge clk)
	begin
		key_n_r <= key_n;
		key_n_r1 <= key_n_r;
		key_n_r2 <= key_n_r1;
	end

wire key_edge = (key_n_r1 == key_n_r2)? 1'b0:1'b1; //边沿检测

reg	[17:0]	cnt; //20ms延时
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		cnt <= 18'd0;
	else if(key_edge)
		cnt <= 18'd0;
	else 
		cnt <= cnt +1'b1;
		
always@(posedge clk or negedge rst_n)//延时20ms时间采样,得到延时消抖输出
	if(!rst_n)
		key_jit <= {KEY_WIDTH{1'b1}};
	else if(cnt == CNT_NUM-1)
		key_jit <= key_n_r2;

reg	[KEY_WIDTH-1:0]	key_jit_r;//对延时消抖输出key_jit延迟锁存

always @(posedge clk or negedge rst_n)
	if (!rst_n) 
		key_jit_r <= {KEY_WIDTH{1'b1}};
    else  
		key_jit_r <= key_jit;

//检测延时消抖输出key_jit下降沿,得到消抖脉冲输出
assign key_pulse = key_jit_r & ( ~key_jit);

//根据消抖脉冲信号,对应按键输出翻转,像自锁开关一样
always @(posedge clk or negedge rst_n)
	if (!rst_n) key_state <= {KEY_WIDTH{1'b1}};
    else if(key_pulse) key_state <= key_state ^ key_pulse;	//当按键未按下时,key_pluse为0,key_state =1;
															//当第一次按下时,key_pluse=1,key_state=1^1=0;
															//当第二次按下时,key_pluse=1;key_state=0^1=1;实现翻转
	else key_state <= key_state;

endmodule

  

 

posted @ 2022-09-17 10:11  xiaoberber  阅读(38)  评论(0编辑  收藏  举报