FPGA初级课程第六讲 单独按键消抖
FPGA初级课程第六讲 单独按键消抖
Hi,大家好!我是至芯科技的李老师。
今天讲课的题目是:单独按键消抖。
本节课我先简要地介绍一下单独按键消抖的物理原理,然后进行单独按键消抖的架构设计和状态转移图设计,再实际演示一下单独按键消抖的建模与仿真,通过仿真查看单独按键消抖的效果。
打开《ZX_NO1.pdf》文件,我们看一下四个轻触开关按键的电路图。
我们打开《26至芯科技奋斗的小孩之altera 系列 第二十六篇 单独按键消抖.pdf》文件。
对于每一个的小实验,我们都可以把它看作是一个小项目,逐步的去分析,设计,调试,最后完成功能。
下面我们就开始我们的“小项目”。
项目名称:单独按键消抖
具体要求:消除按键按下以及抬起时所带来的抖动。
项目分析:
1. 按键电路
2. 抖动的产生
通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。
因而在闭合及断开的瞬间均伴随有一连串的抖动。
3. 按键抖动带来的危害
键抖动会引起一次按键被误读多次。为确保CPU对键的一次闭合仅作一次处理,必须去除键抖动。
在键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。
4. 抖动的一些参数
抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。
这是一个很重要的时间参数,在很多场合都要用到。
按键稳定闭合时间的长短则是由操作人员的按键动作决定的,一般为零点几秒至数秒。
5. 解决办法
一是延时重采样;二是持续采样。
从理论上来说,延时(如10ms)重采样的准确率肯定低于持续采样。
笔者采用持续采样。
好,讲完单独按键消抖的物理原理,我们再回到系统设计上来。
架构图如下图所示。
key_n:带有抖动的低电平有效的按键输入(按键按下为低电平)
click_n:滤除抖动之后的低电平有效的按键波形
系统设计:
1. 工程的名称:key_filter
2. 状态转移图如下:
MASK_TIME : 按键持续保持的时间(笔者选择为10ms)
而我们的程序仅仅是做了一个单纯的10ms滤波,也就是要求按键按下、释放均需经过10ms持续保持时间再确认。
本帖最后由 lcytms 于 2016-11-4 17:14 编辑
下面我们进行建模和仿真。
新建工程文件夹key_filter。
先编写key_filter.v代码。
module key_filter (clk, rst_n, key_n, click_n);
input clk, rst_n;
input key_n;
output reg click_n;
parameter MASK_TIME = 500_000; // 10ms/20ns = 500_000, for checking key hold time
reg cnt;
reg state;
localparam s0 = 1'b0,
s1 = 1'b1;
always @ (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
cnt <= 0;
click_n <= 1;
state <= s0;
end
else
begin
case (state)
s0 : begin
if (key_n)
begin
cnt <= 0;
click_n <= 1;
state <= s0;
end
else
begin
if (cnt < MASK_TIME - 1)
begin
cnt <= cnt + 19'b1;
state <= s0;
end
else
begin
cnt <= 0;
click_n <= 0;
state <= s1;
end
end
end
s1 : begin
if (!key_n)
begin
cnt <= 0;
click_n <= 0;
state <= s1;
end
else
begin
if (cnt < MASK_TIME - 1)
begin
cnt <= cnt + 19'b1;
state <= s1;
end
else
begin
cnt <= 0;
click_n <= 1;
state <= s0;
end
end
end
default : state <= s0;
endcase
end
end
endmodule
本帖最后由 lcytms 于 2016-11-4 17:20 编辑
然后编写Testbench文件,新建key_filter_tb.v。
解析:
模仿按键抖动时,抖动的时间(低电平或者高电平的持续时间)一定不要超过,否则将会被认为按键按下或者抬起。
模仿按键真正按下或者真正抬起时,给予的时间一定要超过抖动(低电平或者高电平的持续时间)的时间。
`timescale 1ns/1ps
module key_filter_tb;
reg clk, rst_n;
reg key_n;
wire click_n;
key_filter #(.MASK_TIME(5))
dut (.clk(clk), .rst_n(rst_n), .key_n(key_n), .click_n(click_n));
initial
begin
clk = 1;
rst_n = 0;
key_n = 1;
#200.1
rst_n = 1;
#200
key_n = 0;
#10
key_n = 1;
#20
key_n = 0;
#80
key_n = 1;
#200
key_n = 0;
#400 //key hold time is long enough
key_n = 1;
#10
key_n = 0;
#20
key_n = 1;
#80
key_n = 0;
#200
key_n = 1;
#200 //key hold time is long enough
#200 $stop;
end
always #10 clk = ~clk;
endmodule
设置仿真。
检查仿真结果。
可以看到本次设计成功地将按键按下以及抬起时的抖动滤除。
页:
[1]
2