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的学习:按键消抖的实现的主要内容,如果未能解决你的问题,请参考以下文章
Linux——Linux驱动之使用内核定时器进行按键消抖的开发实战(内核定时器的基本概念使用要点修改定时周期运行)