FPGA按键去抖verilog代码
按键去抖的原因及其分类就不罗嗦了。
在这里解释一段代码,代码是网上找的,看了半天没懂,无奈查了半天想了半天,终于明白了。。。
module sw_debounce(
clk,
rst_n,
sw1,
sw2,
sw3,
//output
led_d3,
led_d4,
led_d5
);
input clk;
input rst_n;
input sw1,sw2,sw3; //Active low
output led_d3;
output led_d4;
output led_d5;
// ---------------------------------------------------------------------------
// 通过降采样对sw1~sw3 的输入做低通滤波,将其高频分量滤除,得到low_sw 值
// ---------------------------------------------------------------------------
reg [19:0] cnt;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
cnt <= 20'd0;
else
cnt <= cnt + 1'b1;
reg [2:0] low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n)
low_sw <= 3'b111;
else if (cnt == 20'hfffff) //每隔20MS 检测一次按键
low_sw <= {sw3,sw2,sw1};
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
reg [2:0] low_sw_r; //将low_sw 信号锁存一个时钟周期,延时不是真的“锁存”
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
low_sw_r <= 3'b111;
else
low_sw_r <= low_sw;
wire [2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);
//当检测到按键有下降沿变化时,代表该按键被按下,按键有效
reg d1;
reg d2;
reg d3;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
begin
d1 <= 1'b0;
d2 <= 1'b0;
d3 <= 1'b0;
end
else
begin
if ( led_ctrl[0] ) d1 <= ~d1;
if ( led_ctrl[1] ) d2 <= ~d2;
if ( led_ctrl[2] ) d3 <= ~d3;
end
assign led_d5 = d1 ? 1'b1 : 1'b0;
assign led_d3 = d2 ? 1'b1 : 1'b0;
assign led_d4 = d3 ? 1'b1 : 1'b0;
具体原理:通常,按键抖动会产生10--20MS 的毛刺,因此要做的实际上就是在20MS 中采样一次,当
检测到按键下降沿的时候,就认定按下,其他状态忽略。采用 50MHz 晶振,时钟周期是20ns,
else if (cnt == 20'hfffff) //每隔20MS 检测一次按键
low_sw <= {sw3,sw2,sw1};
reg [2:0] low_sw_r; //将low_sw 信号锁存一个时钟周期,延时不是真的“锁存”
always @ ( posedge clk or negedge rst_n )
if (!rst_n)
low_sw_r <= 3'b111;
else
low_sw_r <= low_sw;
wire [2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);
//当检测到按键有下降沿变化时,代表该按键被按下,按键有效
个人觉得,锁存一个时钟周期, 在 FPGA 里的应用实在是太多了,几乎所有的程序都要用到,作用无非
是防止竞争冒险,将一个信号延迟一个时钟周期(low_sw_r[2:0]),原来的信号取反(~low_sw[2:0]),2
个信号与一下,便可以检测到一个下降沿的变化,从而产生一个宽度为一个时钟周期(20ns)的脉冲,然
后将这个脉冲作为控制信号去控制别的进程。。。
上面都是转自一位兄弟的博客,我在这里解释一下关于锁存一个周期是怎么回事。这里的所存是通过非阻塞语句实现的,always块是并行的,同时执行,非阻塞语句的赋值是先计算所有等式右边的表达式的值,然后一齐赋值,在计算期间,也就是在always块结束以前,等式左边等待赋值的变量仍然保持原来的值,这样,第二级锁存器low_sw_r所存的永远是low_sw上一次的值,这样就实现了将信号锁存一个周期。
wire [2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);这是一个很经典的下降沿检测语句。因为非阻塞赋值语句,low_sw_r中是low_sw上一个周期的值,将其与这个周期的low_sw取反后相与,就得到按键是否按下的检测结果,0是没按下,1是按下。
转载自:http://www.cnblogs.com/lamapig/archive/2010/10/03/1841537.html
FPGA按键去抖verilog代码的更多相关文章
- 按键消抖-----verilog
实际系统中常用的按键大部分都是轻触式按键,如下图所示.该按键内部由一个弹簧片和两个固定触点组成,当弹簧片被按下,则两个固定触点接通,按键闭合.弹簧片松开,两个触点断开,按键也就断开了.根据这种按键的机 ...
- 强化版按键消抖Verilog实现
介绍:按键的物理结构导致了会有抖动现象的出现,判断按键是否真正按下,需要把抖动的部分滤波.根据经验可知,抖动一般在20ms内,所以常规的消抖方法是从变化沿出现时刻开始,延时20ms后判断按键的状态.这 ...
- 按键消抖VERILOG实现
对于消抖,有很多种写法.今天分享一下我的写法. 基本思路: 1. 看图 图1 ...
- Linux驱动之定时器在按键去抖中的应用
机械按键在按下的过程中会出现抖动的情况,如下图,这样就会导致本来按下一次按键的过程会出现多次中断,导致判断出错.在按键驱动程序中我们可以这么做: 在按键驱动程序中我们可以这么做来取消按键抖动的影响:当 ...
- javascript中的函数节流和函数去抖
带着问题去尝试 首先我们要知道为什么要用到函数节流和函数去抖?我们带着以下的疑问来进行分析! 1.比如搜索框,你会用到什么事件(change.blur.keyup等)?去做什么效果?2.再比如scro ...
- 【代码】verilog之:按键消抖
此模块完美运行 /*-------------------------------------------------------------------------------------- -- ...
- FPGA低级建模---按键去抖动
FPGA低级建模,原则上一个模块一个功能,如按键去抖动建模中,有两个模块. 1.detect_module 这个是按键检测模块,主要检测按键的高低电平变化,现在按键是按下还是释放. 2.delay_m ...
- 基于FPGA的数字秒表(数码管显示模块和按键消抖)实现
本文主要是学习按键消抖和数码管动态显示,秒表显示什么的,个人认为,拿FPGA做秒表真是嫌钱多. 感谢 感谢学校和至芯科技,笔者专业最近去北京至芯科技培训交流了一周.老师的经验还是可以的,优化了自己的代 ...
- FPGA学习笔记(八)—— 状态机设计实例之独立按键消抖
###### [该随笔中部分内容转载自小梅哥] ######### 独立按键消抖自古以来在单片机和FPGA中都是个不可避免的问题,首先,解释一下什么叫做按键抖动,如图,按键在按下和松开的那个瞬间存在大 ...
随机推荐
- mysql存储引擎简析
一.常见存储引擎特性 Innodb 具有提交.回滚和崩溃恢复能力的事务安全.支持外键.使用mvcc以及行锁来提供事务支持,因此支持高并发.适用于写频繁,并发率高的应用. Myisam 不支持事务和灾难 ...
- VB.NET版机房收费系统---外观层怎样写
外观设计模式.<大话设计模式>第103页具体解说,不记得这块知识的小伙伴能够翻阅翻阅,看过设计模式,敲过书上的样例,仅仅是学习的第一步,接着,假设在我们的项目中灵活应用,把设计模式用出花儿 ...
- Java从零开始学三十二(正则表达式)
一.为什么要有正则 正则表达式可以方便的对数据进行匹配,可以执行更加复杂的字符串验证.拆份.替换功能. 例如:现在要求判断一个字符串是否由数字组成,则可以有以下的两种做法: 不使用正则完成 使用正则完 ...
- OpenCV图像处理篇之阈值操作函数
阈值操作类型 这5种阈值操作类型保留opencv tutorials中的英文名称.依次为: Threshold Binary:即二值化,将大于阈值的灰度值设为最大灰度值.小于阈值的值设为0. Thre ...
- Python Module和Package辨析
Python 基础学习 说明 这不是最基础的新手教程,如需了解Python的数据类型.变量等基础内容,请移步:https://docs.python.org/2/tutorial/index.html ...
- 算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答
目录 1 马虎的算式 2 黄金连分数 3 有理数类 4 幸运数 5 连号区间数 前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 马虎的算式 标题: 马虎的算式 小明 ...
- POJ 1163 The Triangle DP题解
寻找路径,动态规划法题解. 本题和Leetcode的triangle题目几乎相同一样的,本题要求的是找到最大路径和. 逆向思维.从底往上查找起就能够了. 由于从上往下能够扩展到非常多路径.而从下往上个 ...
- 【独立开发人员er Cocos2d-x实战 001】csb文件导出和载入
使用cocos studio进行资源文件导出: 然后在cocosproject中进行载入csb文件: auto myLayout = CSLoader::createNode("/res/ ...
- jquery遍历集合&数组&标签
jquery遍历集合&数组的两种方式 CreateTime--2017年4月24日08:31:49Author:Marydon 方法一: $(function(){ $("inp ...
- 【Oracle】ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
早上使用PL/SQL连接Oracle的时候,报错如下 解决办法: 找到文件listener.ora,新增以下红色区域,注意:路径需要根据自己的Oracle安装路径自行设置 # listener.ora ...