【第一季】CH08_FPGA_Button 按钮去抖动实验
【第一季】CH08_FPGA_Button 按钮去抖动实验
按键的消抖,是指按键在闭合或松开的瞬间伴随着一连串的抖动,这样的抖动将直接影响设计系统的稳定性,降低响应灵敏度。因此,必须对抖动进行处理,即消除抖动的影响。实际工程中,有很多消抖方案,如RS触发器消抖,电容充放电消抖,软件消抖。本章利用FPGA内部来设计消抖,即采取软件消抖。
按键的机械特性,决定着按键的抖动时间,一般抖动时间在5ms~10ms。消抖,也意味着,每次在按键闭合或松开期间,跳过这段抖动时间,再检测按键的状态。只要通过简单的延时就可实现按键的消抖动。
8.1硬件介绍
MIZ702(MIZ702N、MIZ701N看原理图PIN脚定义不一样,配套源码已经改好XDC文件的PIN脚)底板中配套5个独立按键与ZYNQ PL相连,具体请参考对应开发板原理图。由于各个按键独立,消抖过程是一样的,故本节就用板子上的一个按键SW3来模拟实际环境。按键每按一次,对应的LED灯反转一次。即检测按键是否有闭合和断开的过程,如果有,第一次则LED灯点亮,第二次,则LED灯熄灭。
原理图入下图所示
8.2 硬件原理图

PIN脚定义(讲解以MIZ702讲解,MIZ701N只有4个LED 2个按钮):
|
GCLK:Y9(PL输入时钟) LD0:T22 LD1:T21 LD2:U22 LD3:U21 LD4:V22 LD5:W22 LD6:U19 LD7:U14 |
BTNU:T18 BTNC:P16 BTNL:N15 BTNR:R18 BTND:R16 |
8.2时序设计
由于按键固有的特性,在每次闭合和断开时,经过抖动-稳定-抖动-稳定的过程。因此,检测按键是否有按下的过程,则要进行两次消抖处理。通过检测按键输入的值,当检测到BTNC为低电平时,启动计数器,做10ms延时,再检测一次,若BTNC依然为低,则说明,BTNC被按下,设置按键按下标志位。再次检测BTNC,若BTNC为高电平,做10ms延时,第二次检测,若依然为高电平,则说明BTNC已断开,设置BTNC断开标志位,通过两个标志位,可以判断,BTNC已经完成了一次闭合到断开的过程,则led灯反转一次。消抖基本流程如下图所示。
采用状态机来实现上面的流程是非常方便的。通过状态机的切换,按键每次由闭合到断开的过程中,分别产生low_flag和high_flag,当这两个同时为高电平时,led灯实现一次翻转。即第一次按键led高亮,第二次按键led熄灭,第三次led高亮……
8.3程序源码
|
`timescale 1ns / 1ps //----------------------------------------------------------------------------------------------------- /* * 文件名字:Key_Jitter.v * 程序描述: * 作 者: * 修改日期: * 版 本 号: * 版权所有:南京米联电子科技有限公司 */ //----------------------------------------------------------------------------------------------------- module Key_Jitter( input clk_i, input rst_n_i, input key_i, output [3:0] led_o, output [18:0] div_cnt_tb, output [2:0] key_state_tb ); localparam DELAY_Param=19'd499_999;//for project //localparam DELAY_Param=19'd1500; //for simulation //localparam DELAY_Param=19'd10; //No filter jitter reg [3:0] led_o_r; (*KEEP = "TRUE" *)reg [18:0] div_cnt;//10ms去抖时间计数器 always@(posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) div_cnt<=19'd0; else if(div_cnt<DELAY_Param) div_cnt<=div_cnt+1'b1; else div_cnt<=0; end wire delay_10ms=(div_cnt==DELAY_Param) ? 1'b1:1'b0; //按键检测状态机 localparam DETECTER1=3'b000; localparam DETECTER2=3'b001; localparam DETECTER3=3'b010; localparam DETECTER4=3'b011; localparam LED_DIS =3'b100; reg low_flag; reg high_flag; reg [2:0] key_state; always@(posedge clk_i or negedge rst_n_i) begin if(!rst_n_i) begin key_state<=DETECTER1; low_flag<=0; high_flag<=0; led_o_r<=4'b1111; end else if(delay_10ms) //每10ms检测一次,每次检测按键闭合和断开过程,led灯翻转一次 begin case(key_state) DETECTER1 : begin if(key_i!=1'b1) key_state<=DETECTER2; else key_state<=DETECTER1; end DETECTER2 : begin if(key_i!=1'b1) begin low_flag<=1'b1; key_state<=DETECTER3; end else begin key_state<=DETECTER1; low_flag<=low_flag; end end DETECTER3 : begin if(key_i==1'b1) key_state<=DETECTER4; else key_state<=DETECTER3; end DETECTER4 : begin if(key_i==1'b1) begin high_flag<=1'b1; key_state<=LED_DIS; end else begin high_flag<=high_flag; key_state<=DETECTER3; end end LED_DIS : begin if(high_flag & low_flag) begin key_state<=DETECTER1; led_o_r<=~led_o_r; high_flag<=1'b0; low_flag<=1'b0; end else begin led_o_r<=led_o_r; key_state<=key_state; high_flag<=high_flag; low_flag<=low_flag; end end default: begin key_state<=DETECTER1; led_o_r<=0; high_flag<=0; low_flag<=0; end endcase end else begin key_state<=key_state; led_o_r<=led_o_r; high_flag<=high_flag; low_flag<=low_flag; end end assign led_o=led_o_r; assign div_cnt_tb=div_cnt; assign key_state_tb=key_state; endmodule |
8.4程序分析
• 程序中定义了div_cnt计数器,实现10ms消抖延时操作;
• 程序中定义了key_state一段式状态机,该状态机包括5个状态。其中前4个为按键闭合与断开检测与消抖状态,在完成前4个状态后,通过led灯的翻转来表现按键的闭合与断开;
• 程序中定义了两个标志位,分别为low_flag和high_flag。low_flag表示检测到按键按下,即按键闭合,high_flag表示检测到按键弹起,即按键断开。当着两个标志为同时为1时,表示按键完成一次闭合与断开;
• 程序中,对状态机做了循环,来回不停检测按键状态,且每次状态的切换时间是10ms,状态的切换时间,也是按键消抖检测过程。
8.5综合布线前仿真时序
为清晰地表达程序工作流程,在源代码中,添加了div_cnt_tb,div_start_tb,key_state_tb这些信号。且程序中将有意将计数器另外设置一个较小的值,这是为了减少仿真等待的时间。其仿真图如下所示。

8.6 在线逻辑分析仪仿真
对于消抖试验而言,逻辑分析仪不能很直观表现整个设计流程,故该节将放弃使用,直接观察按键按下,LED灯能否正确熄灭和点亮作为试验结果。
8.7输出结果
按键SW4每按一次,LED灯很好地熄灭和点亮。LED灯响应无差错。为清晰的表示消抖的效果,可将延时参数设置很小,可以发现,按键有时候明明已经按下去了,LED却无响应。
8.8小结
按键消抖,是轻触开关必须进行的一项操作。否则,按键将无法使用。在一个工作系统当中,由于按键未消抖,甚至可能直接使系统崩溃。从上面的几个例子也可以看出,无论是按键消抖,还是跑马灯等,设计的前提是要熟练掌握verilog语法。后续章节中,将不在局限于单个文件。在代码量逐渐增加的基础上,将分模块分文件来实现整个系统的功能。
【第一季】CH08_FPGA_Button 按钮去抖动实验的更多相关文章
- 【第一季】CH07_FPGA_RunLED创建VIVADO工程实验
[第一季]CH07_FPGA_RunLED创建VIVADO工程实验 7.1 硬件图片 先来熟悉一下开发板的硬件:LED部分及按钮部分 7.2 硬件原理图 PIN脚定义(讲解以MIZ702讲解,MIZ7 ...
- QQ聊天界面的布局和设计(IOS篇)-第一季
我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...
- 【第一季】CH09_FPGA多路分频器设计
[第一季]CH09_FPGA多路分频器设计 在第七节的学习中,笔者带大家通过一个入门必学的流水灯实验实现,快速掌握了VIVADO基于FPGA开发板的基本流程.考虑到很多初学者并没有掌握好Vivado ...
- Vue2.0 【第一季】第6节 v-model指令
目录 Vue2.0 [第一季] 第6节 v-model指令 第6节 v-model指令 一.一个最简单的双向数据绑定代码: 二.修饰符 三.文本区域加入数据绑定 四.多选按钮绑定一个值 五.多选绑定一 ...
- JAVA入门第一季(mooc-笔记)
笔记相关信息 /** * @subject <学习与创业>作业1 * @author 信管1142班 201411671210 赖俊杰 * @className <JAVA入门第一季 ...
- Asp.Net MVC3 简单入门第一季(三)详解Controller之Filter
前言 前面两篇写的比较简单,刚开始写这个系列的时候我面向的对象是刚开始接触Asp.Net MVC的朋友,所以写的尽量简单.所以写的没多少技术含量.把这些技术总结出来,然后一简单的方式让更多的人很好的接 ...
- Hadoop 2.x从零基础到挑战百万年薪第一季
鉴于目前大数据Hadoop 2.x被企业广泛使用,在实际的企业项目中需要更加深入的灵活运用,并且Hadoop 2.x是大数据平台处理 的框架的基石,尤其在海量数据的存储HDFS.分布式资源管理和任务调 ...
- 《java入门第一季》之Arrays类前传(排序案例以二分查找注意的问题)
根据排序算法,可以解决一些小案例.举例如下: /* * 把字符串中的字符进行排序. * 举例:"dacgebf" * 结果:"abcdefg" * * 分析: ...
- 真爱如血第一季/全集True Blood迅雷下载
第一季 True Blood Season 1 (2008)看点:该剧根据小说<南方吸血鬼>(Southern Vampire)改编,故事围绕路易斯安那州的吸血鬼和人类展开,当日本将人造血 ...
随机推荐
- [BJOI2019]奥术神杖——AC自动机+DP+分数规划+二分答案
题目链接: [BJOI2019]奥术神杖 答案是$ans=\sqrt[c]{\prod_{i=1}^{c}v_{i}}=(\prod_{i=1}^{c}v_{i})^{\frac{1}{c}}$. 这 ...
- 6.3 MRUnit写Mapper和Reduce的单元测试
1.1 MRUnit写单元测试 作用:一旦MapReduce项目提交到集群之后,若是出现问题是很难定位和修改的,只能通过打印日志的方式进行筛选.又如果数据和项目较大时,修改起来则更加麻烦.所以,在将 ...
- MySql的Linux版安装
1,官网下载MySql的Linux版: 下载地址:http://dev.mysql.com//downloads/mysql/ 2.上传到Linux服务器,建议放在/opt/目录下 3.检查当前系统是 ...
- AddLayer和AddTag
using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; pu ...
- SQL中instr和like的使用区别
1.instr函数 instr函数是一个字符串处理函数,它在Oracle/PLSQL中是返回子字符串在源字符串中的位置,如果在源串中没有找到子串,则返回0. instr函数定义如下: /* * 返回子 ...
- linux下如何批量替换多个文件中的某个字符串?
答: sed -i "s/<old_string>/<new_string>/g" `grep "<old_string>" ...
- C++ list 查找
#include <iostream>#include <list>#include <algorithm> using namespace std; int ma ...
- eNSP V100R002C00B500 Setup模拟CE6800
本人操作系统:Windows7 64 下载需要的安装包: eNSP V100R002C00B500 官网下载地址:点击这里 CE6800 官网下载地址:点击这里 USG6000V ...
- Java 正则判断一个字符串中是否包含中文
使用正则判断一个字符串中是否包含中文或者中文字符 代码实现如下: import java.util.regex.Matcher; import java.util.regex.Pattern; /** ...
- centos下如何关闭xdebug扩展
因为只要加载XDEBUG都会导致系统太慢,所以只有在需要调试系统程序的时候才加载XDEBUG扩展.平时一定要把它给注释掉. 只需要在php.ini文件中注释掉xdebug即可. 即: 前面加一个分号即 ...