FPGA的学习:按键消抖的实现

Posted 石小舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FPGA的学习:按键消抖的实现相关的知识,希望对你有一定的参考价值。

首先先来看系统框图和时序图。

接着编写代码实现

`timescale  1ns/1ns

module  key_filter
#(
    parameter CNT_MAX = 20'd999_999 //计数器计数最大值
)
(
    input   wire    sys_clk     ,   //系统时钟50Mhz
    input   wire    sys_rst_n   ,   //全局复位
    input   wire    key_in      ,   //按键输入信号

    output  reg     key_flag        //key_flag为1时表示消抖后检测到按键被按下
                               
);

reg     [19:0]  cnt_20ms    ;   //计数器

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms <= 20'b0;
    else    if(key_in == 1'b1)
        cnt_20ms <= 20'b0;
    else    if(cnt_20ms == CNT_MAX && key_in == 1'b0)
        cnt_20ms <= cnt_20ms;
    else
        cnt_20ms <= cnt_20ms + 1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        key_flag <= 1'b0;
    else    if(cnt_20ms == CNT_MAX - 1'b1)
        key_flag <= 1'b1;
    else
        key_flag <= 1'b0;

endmodule

然后进行仿真文件的编写。

`timescale  1ns/1ns

module  tb_key_filter();

parameter   CNT_1MS  = 20'd19   ,
            CNT_11MS = 21'd69   ,
            CNT_41MS = 22'd149  ,
            CNT_51MS = 22'd199  ,
            CNT_60MS = 22'd249  ;

wire            key_flag        ;   //消抖后按键信号

reg             sys_clk         ;   //仿真时钟信号
reg             sys_rst_n       ;   //仿真复位信号
reg             key_in          ;   //模拟按键输入
reg     [21:0]  tb_cnt          ;   //模拟按键抖动计数器

//初始化输入信号
initial begin
    sys_clk    = 1'b1;
    sys_rst_n <= 1'b0;
    key_in    <= 1'b0;
    #20         
    sys_rst_n <= 1'b1;
end

//sys_clk:模拟系统时钟,每10ns电平翻转一次,周期为20ns,频率为50Mhz
always #10 sys_clk = ~sys_clk;

//tb_cnt:按键过程计数器,通过该计数器的计数时间来模拟按键的抖动过程
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        tb_cnt <= 22'b0;
    else    if(tb_cnt == CNT_60MS)
          //计数器计数到CNT_60MS完成一次按键从按下到释放的整个过程
        tb_cnt <= 22'b0;
    else    
        tb_cnt <= tb_cnt + 1'b1;

//key_in:产生输入随机数,模拟按键的输入情况
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        key_in <= 1'b1;     //按键未按下时的状态为为高电平
    else    if((tb_cnt >= CNT_1MS && tb_cnt <= CNT_11MS)
                || (tb_cnt >= CNT_41MS && tb_cnt <= CNT_51MS))
    //在该计数区间内产生非负随机数0、1来模拟10ms的前抖动和10ms的后抖动
        key_in <= {$random} % 2;    
    else    if(tb_cnt >= CNT_11MS && tb_cnt <= CNT_41MS)
        key_in <= 1'b0;
    //按键经过10ms的前抖动后稳定在低电平,持续时间需大于CNT_MAX
    else
        key_in <= 1'b1;

 

 

 

以上是关于FPGA的学习:按键消抖的实现的主要内容,如果未能解决你的问题,请参考以下文章

FPGA培训专家 V3学院带你学习 按键消抖 和 边缘检测

Linux——Linux驱动之使用内核定时器进行按键消抖的开发实战(内核定时器的基本概念使用要点修改定时周期运行)

09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档

按键消抖学习

Arduino 按键输入检测,消抖示例程序

Simulink HDL Coder FPGA初级开发实践 按键消抖