按键

 

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;

//延时20ms时间采样,得到延时消抖输出
always @(posedge clk or negedge rst_n)
    if (!rst_n)  key_jit <= {KEY_WIDTH{1'b1}};//{{ }}表示复制,{4{a}}等同于{a,a,a,a};所以{13{1‘b1}}就表示将13个1拼接起来,即13’b1111111111111。
    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;
    else key_state <= key_state;

endmodule

 

posted @ 2022-09-19 00:14  xiaoberber  阅读(81)  评论(0编辑  收藏  举报