有时候我们需要用按键去控制一些东西,实质上就是为了获得一个实时变化的高低电平。然而由于按键抖动等干扰,我们并不能获得一个实时变化的电平,如果不去考虑抖动干扰的影响,测得的电平可能与想要的值相反,或者极不稳定。例如在蜂鸣器的使用中,如果我们想要的是按键按下后持续的响声,但由于按键抖动的影响,可能会产生断断续续或者难以控制的刺耳噪音。所以为了消除以上等影响,我们需要进行按键消抖。

如上图所示,在按键按下时候,可能并不是立即由高电平转换为低电平,可能有5~10ms左右的抖动时间。所以为了消除抖动,我们需要去除这抖动的时间。我们假设抖动的时间为20ms。
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_reg <= 1'b1;
delay_cnt <= 32'd0;
end
else begin
key_reg <= key; //在按键没有按下之前,令其值相等
if(key_reg != key) //一旦检测到按键状态发生变化(按键被按下或释放)
delay_cnt <= 32'd1000000; //50M的时钟,每个时钟20ns,延时为20ms 给计数器重新装载
else if(key_reg == key)begin //按键稳定后,开始20ms倒计时
if(delay_cnt > 32'd0)
delay_cnt <= delay_cnt - 1'b1;
else
delay_cnt <= delay_cnt;
end
end
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)begin
key_flag <= 1'b0;
key_value <= 1'b1;
end
else begin
if(delay_cnt == 32'd1)begin //当计数器递减到1时,说明稳定状态持续了20ms
key_falg <= 1'b1; // 标志位置1
key_value <= key; //并寄存此时的按键的值
end
else begin
key_flag <= 1'b0;
key_value <= key_value;
end
end
end
以上就是对按键进行消抖处理的代码。且是单次按击的消抖除了,实际上除了单点还有连续按击和长按改变,长按不变等区别。将在后续章节更新。
635

被折叠的 条评论
为什么被折叠?



