按键消抖-----verilog



/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :key_shake.v
** CreateDate :2015.03
** Funtions : 按键的消抖操作:在复位之后的100us内,不响应按键的操作,在之后有按键按下后,有20ms的延迟,之后输出按键输出.
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved[F].
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:V1.1:clk-->clk_100M, 常数声明放到一起,便于修改。
*******************************************************************************/ module key_shake (
clk_100M,
rst_n, key_in,
key_out
);
input clk_100M; //100Mhz
input rst_n; input key_in;
output key_out; //--------------------------------------
//在复位之后的100us内,不响应按键的操作
localparam t_100us = 'd9999;
localparam t1ms = 'd99999; //定时1ms
localparam t_20ms = 'd20; reg [:] cnt;
reg key_en; //复位之后允许按键输入标志
always @(posedge clk_100M or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= ;
key_en <=;
end
else
begin
if(cnt == t_100us)
begin
key_en <= ;
end
else
begin
key_en <= ;
cnt <= cnt + ;
end
end
end //--------------------------------------------------
wire HtoL_flag; //下降沿标志
wire LtoH_flag; //上升沿标志
reg [:] key_reg;
always @(posedge clk_100M or negedge rst_n)
begin
if(!rst_n)
begin
key_reg <= 'b111; //默认没按下状态为高,按下之后为低.反之则为3'b000;
end
else
begin
key_reg <= {key_reg[:],key_in};
end
end assign HtoL_flag = key_en?(key_reg[:] == 'b10):0; //下降沿检测,一个时钟的高电平
assign LtoH_flag = key_en?(key_reg[:] == 'b01):0; //上升沿检测,一个时钟的高电平
//---------------------------------------------
reg cnt_en; //计数使能标志 reg [:] cnt2;
always @(posedge clk_100M or negedge rst_n)
begin
if(!rst_n)
begin
cnt2 <= 'd0;
end
else if((cnt_en)&&(cnt2 == t1ms))
begin
cnt2 <= 'd0;
end
else if(cnt_en)
begin
cnt2 <= cnt2 + 'd1;
end
else
cnt2 <= 'd0;
end reg [:] cnt3;
always @(posedge clk_100M or negedge rst_n)
begin
if(!rst_n)
begin
cnt3 <= 'd0;
end
else if((cnt_en)&&(cnt2 == t1ms))
begin
if(cnt3 == t_20ms )
cnt3 <= t_20ms;
else
cnt3 <= cnt3 + ;
end
else if(!cnt_en)
cnt3 <= 'd0;
end //----------------------------------
//按键状态机
reg [:] i;
reg key_down; //按键按下标志
reg key_up; //按键释放标志
always @(posedge clk_100M or negedge rst_n)
begin
if(!rst_n)
begin
key_down <= ;
key_up <= ;
i <= ;
cnt_en <= ;
end
else
begin
case(i)
'd0:
begin
key_down <= ;
key_up <= ;
if(HtoL_flag) i <= 'd1; //检测到按下
else if(LtoH_flag) i <= 'd2; //检测到释放按键
else i <= 'd0;
end
'd1:
begin
if(cnt3 == t_20ms )
begin
if(!key_in) //检测到按键依然被按下
begin
key_down <= ; //按键按下成功
i <= 'd3;
cnt_en <= ;
end
else
begin
key_down <= ;
i <= 'd0;
cnt_en <= ;
end
end
else
cnt_en <= ;
end
'd2:
begin
if(cnt3 == t_20ms )
begin
if(key_in) //检测到按键被释放
begin
key_up <= ; //按键释放成功
i <= 'd3;
cnt_en <= ;
end
else
begin
key_up <= ;
i <= 'd0;
cnt_en <= ;
end
end
else
cnt_en <= ;
end
'd3:
begin
key_up <= ;
key_down <= ;
i <= 'd0;
end
default:i <= 'd0;
endcase
end
end assign key_out = key_down; //当按键被按下有效时
// assign key_out = key_up; //当按键被释放后才有效时
endmodule
测试代码如下:
/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :key_testbench.v
** CreateDate :2015.03
** Funtions :按键消抖的测试文件
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved.
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:
*******************************************************************************/ module key_testbench; reg clk;
reg rst_n;
reg key_in;
wire key_out; key_shake key_shake_1(
.clk,
.rst_n, .key_in,
.key_out
); localparam tck = ;
localparam t = /tck; always #(t/) clk = ~clk; task key_in_down;
begin
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
end
endtask task key_in_up;
begin
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
#(*t) key_in = ;
end
endtask initial
begin
clk = ;
rst_n = ;
key_in = ; #(*t) rst_n = ; #(*t);
#(*t) key_in_down;
#(*t);
#(*t) key_in_up; #(*t);
#(*t) repeat() key_in_down; //按下时抖动 #(*t); //按下时间 #(*t) repeat() key_in_up; //释放时抖动 end endmodule
仿真结果:
1、在复位之后100us之前按下按键时,不响应。

2、抖动(按下后20ms之内释放)。


如果将按键按下有效时刻、按键释放有效时刻和按键所处状态全部表现出来,则代码稍作修改即可:
/********************************Copyright**************************************
**----------------------------File information--------------------------
** File name :key_shake.v
** CreateDate :2015.03
** Funtions : 按键的消抖操作:在复位之后的100us内,不响应按键的操作,在之后有按键按下后,有20ms的延迟,检测,然后松开时也有20ms的检测,之后输出按键输出.
** Operate on :M5C06N3L114C7
** Copyright :All rights reserved[F].
** Version :V1.0
**---------------------------Modify the file information----------------
** Modified by :
** Modified data :
** Modify Content:V1.1:clk-->clk_100M, 常数声明放到一起,便于修改。
*******************************************************************************/ module key_shake (
clk,
rst_n, key_in,
key_down_out,
key_up_out,
key_in_out
);
input clk; //24Mhz
input rst_n; input key_in;
output key_down_out; //按下输出
output key_up_out; //释放输出
output key_in_out; //跟随输入输出 //--------------------------------------
//在复位之后的100us内,不响应按键的操作
parameter t_20ms = 'd20; `define CLK_20M
// `define CLK_24M
// `define CLK_50M `ifdef CLK_20M
parameter t_100us = 'd1999;
parameter t1ms = 'd19999; //定时1ms
`endif `ifdef CLK_20M
parameter t_100us = 'd2399;
parameter t1ms = 'd23999; //定时1ms
`endif `ifdef CLK_20M
parameter t_100us = 'd4999;
parameter t1ms = 'd49999; //定时1ms
`endif reg [:] cnt;
reg key_en; //复位之后允许按键输入标志
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt <= ;
key_en <=;
end
else
begin
if(cnt == t_100us)
begin
key_en <= ;
end
else
begin
key_en <= ;
cnt <= cnt + ;
end
end
end //--------------------------------------------------
wire HtoL_flag; //下降沿标志
wire LtoH_flag; //上升沿标志
reg [:] key_reg;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_reg <= 'b111; //默认没按下状态为高,按下之后为低.反之则为3'b000;
end
else
begin
key_reg <= {key_reg[:],key_in};
end
end assign HtoL_flag = key_en?(key_reg[:] == 'b10):0; //下降沿检测,一个时钟的高电平
assign LtoH_flag = key_en?(key_reg[:] == 'b01):0; //上升沿检测,一个时钟的高电平
//---------------------------------------------
reg cnt_en; //计数使能标志
reg [:] cnt2;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt2 <= 'd0;
end
else if((cnt_en)&&(cnt2 == t1ms))
begin
cnt2 <= 'd0;
end
else if(cnt_en)
begin
cnt2 <= cnt2 + 'd1;
end
else
cnt2 <= 'd0;
end reg [:] cnt3;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt3 <= 'd0;
end
else if((cnt_en)&&(cnt2 == t1ms))
begin
if(cnt3 == t_20ms )
cnt3 <= t_20ms;
else
cnt3 <= cnt3 + ;
end
else if(!cnt_en)
cnt3 <= 'd0;
end //----------------------------------
//按键状态机
reg [:] i;
reg key_down; //按键按下标志
reg key_up; //按键释放标志
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_down <= ;
key_up <= ;
i <= ;
cnt_en <= ;
end
else
begin
case(i)
'd0:
begin
key_down <= ;
key_up <= ;
if(HtoL_flag) i <= 'd1; //检测到按下
else if(LtoH_flag) i <= 'd2; //检测到释放按键
else i <= 'd0;
end
'd1:
begin
if(cnt3 == t_20ms )
begin
if(!key_in) //检测到按键依然被按下
begin
key_down <= ; //按键按下成功
i <= 'd3;
cnt_en <= ;
end
else
begin
key_down <= ;
i <= 'd0;
cnt_en <= ;
end
end
else
cnt_en <= ;
end
'd2:
begin
if(cnt3 == t_20ms )
begin
if(key_in) //检测到按键被释放
begin
key_up <= ; //按键释放成功
i <= 'd3;
cnt_en <= ;
end
else
begin
key_up <= ;
i <= 'd0;
cnt_en <= ;
end
end
else
cnt_en <= ;
end
'd3:
begin
key_up <= ;
key_down <= ;
i <= 'd0;
end
default:i <= 'd0;
endcase
end
end //---------------------------
reg key_out;
always @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
key_out <= ;
end
else
begin
if(key_down)
key_out <= ; //按下为低
else if(key_up)
key_out <= ; //释放为高
else
key_out <= key_out; //否则保持
end
end assign key_down_out = key_down; //当按键被按下有效时
assign key_up_out = key_up; //当按键被释放后才有效时
assign key_in_out = key_out;
endmodule
仿真:
按键消抖-----verilog的更多相关文章
- 强化版按键消抖Verilog实现
介绍:按键的物理结构导致了会有抖动现象的出现,判断按键是否真正按下,需要把抖动的部分滤波.根据经验可知,抖动一般在20ms内,所以常规的消抖方法是从变化沿出现时刻开始,延时20ms后判断按键的状态.这 ...
- 按键消抖VERILOG实现
对于消抖,有很多种写法.今天分享一下我的写法. 基本思路: 1. 看图 图1 ...
- Verilog HDL那些事_建模篇笔记(实验三:按键消抖)
实验三:按键消抖 首先将按键消抖功能分成了两个模块,电平检查模块和10ms延迟模块.电平检测模块用来检测按键信号的变化(是否被按下),10ms延迟模块用来稳定电平检查模块的输入,进而稳定按键信号,防止 ...
- 【代码】verilog之:按键消抖
此模块完美运行 /*-------------------------------------------------------------------------------------- -- ...
- 09A-独立按键消抖实验01——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习状态机的设计思想并以此为基础实现按键消抖 2.单bit异步信号同步化以及边沿检测 3.在激励文件中学会使用随机数发生函数$random 4.仿真模 ...
- FPGA学习笔记(八)—— 状态机设计实例之独立按键消抖
###### [该随笔中部分内容转载自小梅哥] ######### 独立按键消抖自古以来在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大 ...
- 09B-独立按键消抖实验02——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.复习按键的设计 2.用模块化设计的方式实现每次按下按键0,4个LED显示状态以二进制加法格式加1,每次按下按键1,4个LED显示状态以二进制加法格式减 ...
- 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...
- 按键消抖——task任务和仿真平台搭建
一.按键抖动原理 按键抖动原理:按键存在一个反作用弹簧,因此当按下或者松开时均会产生额外的物理抖动,物理抖动会产生电平的抖动. 消抖方法:一般情况下,抖动的总时间会持续20ms以内,按下按键后,等20 ...
随机推荐
- HDU 1058 Humble Numbers(离线打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1058 解题报告:输入一个n,输出第n个质因子只有2,3,5,7的数. 用了离线打表,因为n最大只有58 ...
- python 列表推导式
squares = [x**2 for x in range(10)] 相当于squares = map(lambda x: x**2, range(10)),但是更简洁和易读.傻逼才会用最古老的fo ...
- HTTP状态码(响应码)
HTTP状态码(响应码)用来表明HTTP请求是否已经成功完成.HTTP响应类型一共分五大类:消息响应,成功响应,重定向,客户端错误,服务器端错误. 下表列出了所有HTTP状态码,以及他们各自所代表的含 ...
- PO、VO、DAO、BO、POJO
一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择.二.VO :(value object) , ...
- OpenCV成长之路(10):视频的处理
视频中包含的信息量要远远大于图片,对视频的处理分析也越来越成为计算机视觉的主流,而本质上视频是由一帧帧的图像组成,所以视频处理最终还是要归结于图像处理,但在视频处理中,有更多的时间维的信息可以利用.本 ...
- git 教程(7)--撤销修改
自然,你是不会犯错的.不过现在是凌晨两点,你正在赶一份工作报告,你在readme.txt中添加了一行:
- div 加滚动条
div 加滚动条的方法: <div style="position:absolute; height:400px; overflow:auto"></div> ...
- 取得DIV的ID还是CLASS
无论你想取得DIV的ID还是CLASS 最重要的是找到你想取值的DIV对象.要取得DIV对象的方法有很多.常用的有2个,一个是根据ID,用var div=document.getElementById ...
- Java程序优化的一些最佳实践(转)
衡量程序的标准 衡量一个程序是否优质,可以从多个角度进行分析.其中,最常见的衡量标准是程序的时间复杂度.空间复杂度,以及代码的可读性.可扩展性.针对程序的时间复杂度和空间复杂度,想要优化程序代码,需要 ...
- android studio从1.5更新到2.0后terminal无法运行gradle命令,提示无法找到gradle命令
android studio从1.5更新到2.0后terminal无法运行gradle命令,提示无法找到gradle命令. 'gradle' 不是内部或外部命令,也不是可运行的程序 或批处理文件. 设 ...