由于普通物理按键存在反作用弹簧,因此当按下或者松开时均会产生额外的物理抖动,物理抖动便会产生电平的抖动。在按键从按下再到松开的过程中,其电平变化如图2.2.1所示,上为理想波形输出,下为实际波形输出。
图2.2.1 按键抖动
因此,对于转变中间过程存在的跳变,我们需要将其去除,一般来说,噪声仅存在与一段时间内,如20ms。当检测到跳变沿后的开始进行计时,在计数时间内如果出现跳变则重新开始及时,知道在一定时间内没有检测到跳变沿为止 ,则认为键入的数据已经达到稳定的状态。
按键消抖模块代码如下:
module key_shape(
input key,
input clk, //系统时钟50m
output reg key_flag
);
reg kt=0;
reg rs=0;
reg rf=0;
always@(posedge clk)
kt<=key;
always@(posedge clk)
begin
rs<=key&(!kt);
rf<=(!key)&kt;
end
wire [27:0] t20ms=28'd1000000;
reg [27:0] cn_begin=0;
reg [27:0] cn_end=0;
always@(posedge clk)
if((cn_begin==t20ms)&(cn_end==t20ms))
cn_begin<=0;
else if((rs)&(cn_begin<t20ms))
cn_begin<=cn_begin+1;
else if((cn_begin>0)&(cn_begin<t20ms))
cn_begin<=cn_begin+1;
always@(posedge clk)
if(cn_end>t20ms)
cn_end<=0;
else if(rf&(cn_begin==t20ms))
cn_end<=cn_end+1;
else if(cn_end>0)
cn_end<=cn_end+1;
always@(posedge clk)
key_flag<=(cn_begin==1)?1:0;
endmodule