Verilog-按键消抖

本文介绍了如何使用Verilog语言设计一个按键消抖电路,通过计数器检测电平稳定性,消除物理抖动影响。同时提供了测试bench的示例以及仿真结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#学习记录#

1  按键消抖

  普通的按键在按下或者松开时均会产生额外的物理抖动,物理抖动便会产生电平抖动,并且抖动的次数和间隔时间都是不可预期的。我们需要消除抖动来减少对外部设备的影响。一般的抖动的总时间会在20ms以内,因此需要一个计数器对电平的状态进行计时。把电平持续时间小于20ms的状态认为是抖动,而把电平持续时间大于20ms认为是电平的稳定状态。

2  按键消抖的Verilog描述

2.1  代码

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Mr-pn-junction
// 
// Create Date: 2023/12/05 08:29:08
// Design Name: 
// Module Name: key_filter
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module key_filter
 #(cnt_max = 20'd999_999)
(
    input clk,
    input rst_n,
    input key_in,
    output reg key_flag

);
    reg [19:0] cnt;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        cnt <= 20'd0;
    else if (key_in)
        cnt <= 20'd0;
    else if(cnt == cnt_max)
        cnt <= cnt_max;
    else
        cnt <= cnt +20'd1;
end
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        key_flag <= 1'b0;
    else if (cnt ==(cnt_max - 20'd1))
        key_flag <= 1'b1;
    else
        key_flag <= 1'b0;
end
    
        
endmodule

2.2  testbench

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: Mr-pn-junction
// 
// Create Date: 2023/12/05 08:40:43
// Design Name: 
// Module Name: key_filter_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module key_filter_tb ();
    reg clk;
    reg rst_n;
    reg key_in;
    reg [7:0] cnt_tb;
    wire key_flag;
key_filter
#(.cnt_max(20'd50))
 test(
    .clk(clk),
    .rst_n(rst_n),
    .key_in(key_in),
    .key_flag(key_flag)

);
initial begin
    clk = 1'b1;
    rst_n = 1'b0;
    #15
    rst_n = 1'b1;
    #5000
    $stop;
end
always #10 clk = ~clk;
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt_tb <= 8'd0;
    else if(cnt_tb == 8'd255)
        cnt_tb <= 8'd0;
    else 
        cnt_tb <= cnt_tb +2'd1;
end
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        key_in <= 1'b1;
    else if((cnt_tb <= 8'd19)||(cnt_tb >=8'd169))
        key_in <= 1'b1;
    else if ((cnt_tb>=8'd19)&&(cnt_tb<= 8'd49)||(cnt_tb>= 8'd149)&&(cnt_tb<=169))
        key_in <= {$random}%2;
    else
        key_in <= 1'b0;

end
endmodule

2.3  仿真结果

图1  按键消抖仿真结果 

参考文献

[1] 按键消抖(verilog&vivado).按键消抖(Verilog&Vivado)_c语言按键消抖-CSDN博客

[2] 按键消抖verilog.按键消抖Verilog_按键消抖verilog代码-CSDN博客 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值