按键消抖检测的实现"/>
Verilog中按键消抖检测的实现
Verilog按键消抖是FPGA学习时的一个入门教程,为避免眼高手低,还是再次分析与记录一下。此处着重介绍按键消抖的基本原理,对按键消抖与检测的关键技术进行分析,并进行功能仿真。
一、按键消抖基本原理
1、按键消抖必要性
物理按键释放与按下时均会出现抖动,抖动时间约为5-10ms。这就意味着,在按键按下以及释放的5-10ms内,按键的输出为高电平还是低电平是不断抖动的,在0-1之间频繁切换。
如果不进行按键消抖操作,会出现异常触发。比如按键按下一次,但是检测电路将m次抖动也检测进去,会造成输出异常。
2、按键消抖原理
按键消抖原理简单,即通过适当延迟,通过检测延迟前后按键输出电平值,判断按键是否被按下或是释放。延迟使得按键抖动部分不会被检测到,滤除掉抖动的影响,实现了按键消抖。而不必担心因为按键消抖延迟时间的存在,导致真实按下或释放按键被漏检。(因为检测延迟时间极短为10ms,试想,要出现漏检至少应该100下/s,这是不可能的)
二、按键消抖检测关键技术
边沿检测
按键检测实际为边沿检测,在不同电路设计下按键按下与释放对应于不同的输出电压,但是无非就是按下为0释放为1,或者按下为1释放为0的区别。
上升沿检测:检测信号从0-1的变化,检测形式为 ~a_r & a(a为信号当前值,a_r为信号上次采样值)
下降沿检测:检测信号从1-0的变化,检测形式为 a_r & ~a (a为信号当前值,a_r为信号上次采样值)
三、仿真相关
假设按键key0-3,按下输出为0,释放输出为1,按键抖动为10ms,要求检测按键出现按下操作。
实现代码如下:
`timescale 1ns / 1ps
//
// Company:
// Engineer: CLL
//
// Create Date: 2020/03/28 13:06:39
// Design Name:
// Module Name: key_scan
// Project Name:
// Target Devices:
// Tool Versions:
// Description: key_scan
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module key_scan(input [3:0]key,input clk,input rst_n,output [3:0]flag);
parameter CNT_10MS = 4'b0011;//假设延时4个时钟周期对应10ms(易于功能仿真实现)
// internal signal
reg [3:0]key_n;
reg [3:0]key_r;
reg [3:0]cnt;
// delay module
always@(posedge clk or negedge rst_n)
beginif(!rst_n)begincnt <= 1'b0;endelse if(cnt == CNT_10MS)begincnt <= 1'b0;endelsebegincnt <= cnt + 1'b1;end
end
// key input module
always@(posedge clk or negedge rst_n)
beginif(!rst_n)beginkey_n <= 4'b1111;key_r <= 4'b1111;endelse if(cnt == CNT_10MS)beginkey_n <= key;key_r <= key_n;end
end
// key scan module
assign flag = ~key_n & key_r;
//always@(posedge clk or negedge rst_n)
//begin
// if(!rst_n)
// begin
// flag <= 4'b0000;
// end
// else
// begin
// flag <= ~key_n & key_r;
// end
//end
endmodule
为保证输出及时,flag边沿判断部分最好是组合逻辑;
测试文件如下:
以输入key值短时间内频繁反转模拟按键抖动;延迟4个时钟周期模拟实际的10ms延迟;
`timescale 1ns / 1ps
//
// Company:
// Engineer: CLL
//
// Create Date: 2020/03/29 10:00:24
// Design Name:
// Module Name: key_scan_tsb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module key_scan_tsb();
// port
reg clk;
reg rst_n;
reg [3:0]key;
wire [3:0] flag;
// clk
initial
beginclk = 0;forever #5 clk = ~clk;
end
// rst_n
initial
beginrst_n = 1;#10 rst_n = 0;#10 rst_n = 1;
end
//
initial
beginkey = 4'b1111;#20repeat(9) #2 key[0] = ~key[0];//模拟抖动key[0] = 0;#100repeat(9) #2 key[1] = ~key[1];//模拟抖动key[1] = 0;#100repeat(9) #2 key[2] = ~key[2];//模拟抖动key[2] = 0;#100repeat(9) #2 key[3] = ~key[3];//模拟抖动key[3] = 0;
end
// inst
key_scan minst(.clk(clk),.rst_n(rst_n),.key(key),.flag(flag)
);
endmodule
仿真结果如下:
可以看出,电路按照10ms延迟检测按键值,一旦出现1-0情况,即输出按键检测到信号,即flag对应位置1;
更多推荐
Verilog中按键消抖检测的实现
发布评论