FPGA-按键消抖

发布于:2025-03-11 ⋅ 阅读:(17) ⋅ 点赞:(0)

按键消抖

1. 原理

在这里插入图片描述

2. 关键程序实现
always @(posedge clk or negedge rst) begin
    if(!rst)begin
        cnt_wait <= 26'd0;
    end else if(flag_nege || flag_pose)begin
        cnt_wait <= 26'd1;
    end else if(cnt_wait == MAX_CNT) begin
        cnt_wait <= 26'd0;
    end else if(cnt_wait > 26'd0 && cnt_wait < MAX_CNT)begin
        cnt_wait <= cnt_wait + 26'd1;
    end
end

always @(posedge clk or negedge rst) begin
    if(!rst)begin
        key_scan1 <= 4'b1111;
        key_scan2 <= 4'b1111;
    end else if(cnt_wait == MAX_CNT)begin
        key_scan1 <= key_in;
        key_scan2 <= key_scan1;
    end else begin
        key_scan2 <= key_scan1;
    end
end
3. 仿真波形

在这里插入图片描述

4. 源代码
module key(
    input                               clk                        ,
    input                               rst                        ,
    input              [   3:0]         key_in                     ,
    output             [   3:0]         key_out_down               ,           
    output             [   3:0]         key_out_up                     
);

wire                                    key_tmp = &key_in          ;

reg                    key_in_r2                  ;
reg                    key_in_r1                  ;

always @(posedge clk or negedge rst)begin
    if(!rst)begin
        key_in_r1 <= 1'b1;
        key_in_r2 <= 1'b1;
    end else begin
        key_in_r1 <= key_tmp;
        key_in_r2 <= key_in_r1;
    end
end

wire                                    flag_nege = key_in_r2 & !key_in_r1;//
wire                                    flag_pose = !key_in_r2 & key_in_r1;//


reg                    [  25:0]         cnt_wait                   ;
// localparam  MAX_CNT = 50_000_000/50;
localparam                              MAX_CNT = 1_000_000 - 1    ;
always @(posedge clk or negedge rst) begin
    if(!rst)begin
        cnt_wait <= 26'd0;
    end else if(flag_nege || flag_pose)begin
        cnt_wait <= 26'd1;
    end else if(cnt_wait == MAX_CNT) begin
        cnt_wait <= 26'd0;
    end else if(cnt_wait > 26'd0 && cnt_wait < MAX_CNT)begin
        cnt_wait <= cnt_wait + 26'd1;
    end
end

reg                    [   3:0]         key_scan1                  ;
reg                    [   3:0]         key_scan2                  ;
always @(posedge clk or negedge rst) begin
    if(!rst)begin
        key_scan1 <= 4'b1111;
        key_scan2 <= 4'b1111;
    end else if(cnt_wait == MAX_CNT)begin
        key_scan1 <= key_in;
        key_scan2 <= key_scan1;
    end else begin
        key_scan2 <= key_scan1;
    end
end

// wire                   [   3:0]         kay_val = !key_scan1 & key_scan2;  !不行   !的优先级低
wire                   [   3:0]         kay_val_down = ~key_scan1 & key_scan2;//
wire                   [   3:0]         kay_val_up = key_scan1 & ~key_scan2;//

assign key_out_down = kay_val_down;
assign key_out_up = kay_val_up;



endmodule