按键消抖
按键是FPGA实验工程中常见的电子元器件,通常用作系统复位信号或者控制。外部信号的输入。按键消抖主要针对的是机械弹性开关(按下去,一旦松开就会弹上去),当机械触点断开、闭合时,由于机械触点的弹性作用,按键开关在闭合时不会立刻稳定的接通,在断开时也不会一下子断开。按键在闭合和断开的瞬间会有一连串的抖动,为了保证系统能够正确识别按键开关,必须进行消抖处理。
按键消抖分为硬件消抖和软件消抖,硬件消抖会使用额外的器件,占用空间,增加布局布线复杂度。这里讲的是软件消抖,适用于按键比较多的情况。
设计目标
按键每次按下后,系统能够检测到按键仅被按下了一次,而不是因抖动发生重复按下的情况。
设计方法
设计打算应用延时程序去除抖动部分。
cnt_20ms为中间变量,当key_in高电平时,cnt_20ms清零,为低电平时加一。当计数值达到999999-1时,cnt_20ms保持最大值不变,直到遇到key_in高电平清零,这样可以防止因抖动多次检测到按键信号,保证按键按下只产生一个key_flag脉冲。
代码实现
下面直接上代码:
module key_filter
#(
parameter CNT_MAX = 20'd999_999
)
(
input sys_clk ,
input rst_n ,
input key_in ,
output reg key_flag
);
reg [19:0] cnt_20ms;
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n == 1'b0)
cnt_20ms <= 20'd0;
else if(key_in == 1'd1)
cnt_20ms <= 20'd0;
else if(cnt_20ms == CNT_MAX )
cnt_20ms <= CNT_MAX;
else
cnt_20ms <= cnt_20ms + 20'd1;
end
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n == 1'b0)
key_flag <= 1'd0;
else if(cnt_20ms == CNT_MAX - 20'd1)
key_flag <= 1'd1;
else
key_flag <= 1'd0;
end
endmodule
仿真文件:
`timescale 1ns/1ns
module key_filter_tb();
reg sys_clk ;
reg rst_n ;
reg key_in ;
reg [7:0] cnt;
wire key_flag;
parameter M = 249;
initial begin
sys_clk = 1'd0;
forever #10 sys_clk = ~sys_clk;
end
initial begin
rst_n <= 1'd0;
#20
rst_n <= 1'd1;
end
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n == 1'd0)
cnt <= 8'd0;
else if(cnt == M)
cnt <= 8'd0;
else
cnt <= cnt + 8'd1;
end
always@(posedge sys_clk or negedge rst_n)begin
if(rst_n == 1'd0)
key_in <= 1'd0;
else if(((cnt>8'd19) && (cnt<=8'd69)) || ((cnt>8'd149) && (cnt<=8'd199)) )
key_in <= {$random} % 2 ;
else if((cnt>8'd69)&& (cnt<=8'd149))
key_in <= 1'd0;
else
key_in <= 1'd1;
end
key_filter
#(
.CNT_MAX (20'd24)
)
key_filter_inst
(
.sys_clk (sys_clk) ,
.rst_n (rst_n) ,
.key_in (key_in) ,
.key_flag (key_flag)
);
endmodule
仿真结果如图所示,按键按下(key_in长保持低电平时)两次产生了两个脉冲信号,和绘制波形图结果一致。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)