按键消抖原理
由于按键的机械弹簧结构,在按键按下与释放的过程中,存在类似接触不良,断断续续的信号,导致电平信号的抖动。
在C程序中一般通过延时函数解决,根据按键速度,一般延时20ms之后再重新对引脚判断是否真正按下,来解决抖动问题。
在FPGA中可以通过对信号的快速精准判断,只需要根据电平持续时间来解决抖动问题,按键按下一般会有20ms以上的电平平稳时间,就是通过按键的边沿开始计算,只要20ms中没有多个边沿触发,就说明不是抖动。
状态划分与转移
共4个状态:
- 空闲态,没有按键按下
- 按下抖动态,正在按下,信号不平稳
- 按下态,按下信号出去稳定状态
- 释放抖动态,正在释放按键,信号不平稳
状态转移,根据按键边沿信号和时间值。
仿真源文件中的编码
task任务
可以使用task任务,创建任务后,可以多次调用:
task press_key;
input [1:0]flag;//空闲、按下抖动、按下、释放抖动
begin
case(flag)
0:begin
Key = 1;
#20000000;
end
1:
repeat(5)begin
rand = {$random(2)} % 10000000;
#rand Key = ~Key;
end
2:begin
Key = 0;
#20000000;
end
3:
repeat(5)begin
rand = {$random(2)} % 10000000;
#rand Key = ~Key;
end
endcase
end
endtask
调用如同函数调用,直接填写参数值就可以传递给input变量了:
press_key(0);
press_key(1);
press_key(2);
随机数random
上边还有:随机数
rand = {$random(2)} % 10000000;
$random(2): 会产生一个随机数
{$random(2)}:对随机数取绝对值
{$random(2)} % 10000000 :对随机数取绝对值后再取余,限制其范围
循环repeat
循环体
repeat(5)begin
//循环体
end
:表示循环5次
亚稳态现象的优化
通过多级触发器进行信号优化,信号的稳定状态和正确率提高了,不过判断信号的时间略微延迟。
一般通过2级触发器就可以达到一个较好的稳定水平。