按键消抖电路如何实现?

余你余生 / 2023-07-27 / 原文

请设计一个按键消抖电路?

按键消抖 :按键消抖_百度百科 (baidu.com)

module  key_debounce(
input         sys_clk       ,    //20ns
input         sys_rst_n     ,
input         key           ,
//output   reg  key_flag    ,    //正点原子中 将表示信号作为一路输出信号使用
output   reg  key_vaule      
);

parameter   N=4     ;         //20ms/20ns =1000_000   设置小一点的值(4) 好仿真
reg [19:0]  cnt             ;  
reg         key_reg         ;
reg         key_flag        ; //这里我将标志信号作为一个内部信号使用

always@(posedge  sys_clk or negedge sys_rst_n)  begin
    if(!sys_rst_n) begin 
        key_reg<=1'b1;
        cnt<='d0;
    end 
    else begin 
        key_reg<=key;           //寄存按键状态
        if(key_reg!=key)        //处于振荡阶段
            cnt<=N;
        else if(key_reg==key) begin  //处于稳定阶段 计数20ms
            if(cnt>'d0)
                cnt<=cnt-'d1;
            else 
                cnt<=cnt;
        end 
    end 
end 

always@(posedge sys_clk or negedge sys_rst_n) begin 
    if(!sys_rst_n) begin 
        key_flag<=1'b0;
        key_vaule<=1'b1;
    end 
    else if(cnt=='d1) begin    //处于稳定20ms 即判断按下按键
        key_flag<=1'b1;        //产生一个标志信号 表示按键按下
        key_vaule<=key;        //产生消抖的按键信号 即稳定信号
    end 
    else begin 
        key_flag<=1'b0;
        key_vaule<=key_vaule;
    end 
end 
endmodule 
`timescale  1ns/1ns
module  tb_key_debounce();
reg     sys_clk       ;    
reg     sys_rst_n     ;
reg     key           ;
//wire    key_flag      ;
wire    key_vaule     ;

initial begin 
    key                          <= 1'b1;
    sys_clk                      <= 1'b0;
    sys_rst_n                    <= 1'b0; 
    #20           sys_rst_n      <= 1'b1;  //在第20ns的时候复位信号信号拉高 
    #30           key            <= 1'b0;  //在第50ns的时候按下按键
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #170          key            <= 1'b1;  //在第300ns的时候松开按键
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动
    #170          key            <= 1'b0;  //在第550ns的时候再次按下按键
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #170          key            <= 1'b1;  //在第800ns的时候松开按键
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动
    #20           key            <= 1'b0;  //模拟抖动
    #20           key            <= 1'b1;  //模拟抖动

end 

always #10 sys_clk<=~sys_clk;

key_debounce    key_debounce_inst(
.sys_clk    (sys_clk  )   ,    
.sys_rst_n  (sys_rst_n)   ,
.key        (key      )   ,
//.key_flag   (key_flag )   ,
.key_vaule  (key_vaule)     
);

endmodule 

波形图:在设置N=4 下进行仿真

以上是本人对按键消抖电路的总结,若有不对的地方,敬请指正,万分感谢。

参考资料:1、正点原子开拓者FPGA开发按键控制蜂鸣器实验