按键消抖-----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 ...
随机推荐
- Android内存性能优化(内部资料总结)
eoe上看到的一个很好的文章 摘抄了下来留着自己看看 刚入门的童鞋肯能都会有一个疑问,Java不是有虚拟机了么,内存会自动化管理,我们就不必要手动的释放资源了,反正系统会给我们完成.其实Java中没有 ...
- 移动端rem切图
1.为什么用rem 根据屏幕大小,自动调整大小 2.如何使用rem 分以下几步 a.用ps把设置稿弄成640px或者750px的(记得等比例缩放) b.调试时记得把浏览器默认最小字体设置为最小.手机端 ...
- job_queue_processes参数讲解
http://blog.sina.com.cn/s/blog_62defbef0101opv0.html http://blog.163.com/donfang_jianping/blog/stati ...
- 如何预览github中的html页面
在github里面的文件路径是https://github.com/gavin125/Sass-test/blob/master/html/index.html 那么我们需要在这个地址前面加上http ...
- Java实现读取文件夹下(包括子目录)所有文件的文件名
在编程的过程中,经常会用到对文件的读写操作等.比如,找出某一个文件夹下的所有文件名等. 下面的程序给出了,获取某一给定文件夹下所有文件的绝对路径的程序.可以作为某一个模块,在需要的时候直接使用. pa ...
- Border Tree笔记
最近在学这个东西(当然不是行道树了QAQ..),感觉挺鬼畜的,整个人都不太好了..(特别是鬼畜的sone爷代码与讲稿),感觉他写的并不是普及向算法...?
- GitHub访问速度慢的解决方法
# Github 103.245.222.249 github.global.ssl.fastly.net 103.245.222.133 assets-cdn.github.com 23.235.4 ...
- NUI控件扩展
摘要:NUI组件是公司新一代的前端开发框架,它精致优雅的前端编程模型,是大家能够,或者想接受学习它的重要原因,在使用它的时候,一定不免会想增加自己的控件,让别人也能够如此优雅的使用. 其实NUI的扩展 ...
- java servlet的工作原理
servlet本质上就是java类嘛.不过是有特殊规范的java类而已.下面就说一说为什么servlet要有特殊规范. 首先,考虑一下什么地方用servlet,WEB应用,而且是需要servlet容器 ...
- ERROR Cannot determine the location of the VS Common Tools Folder
参考:ERROR Cannot determine the location of the VS Common Tools Folder http://blog.csdn.net/m3728975 ...