文章目录

  • 前言
  • 一、独立按键消抖原理
  • 二、按键消抖程序实现(Verilog)
    • 1.按键触发判断
    • 2.计数器模块实现
    • 3.按键状态更新
    • 4.按键控制led亮灭
  • 三、仿真测试文件编写
  • 四、编译结果

前言

利用verilog语言实现独立按键消抖,文章首先对按键抖动产生的原因、消抖原理进行简要解释;之后详细阐述各模块verilog语言实现方法;最后利用四个独立按键控制led亮灭,在vivado下进行源码设计与仿真。(完成程序代码附在文章结尾)


一、独立按键消抖原理

按键一般是机械弹性开关,由于机械触点的弹性作用,机械触点断开、闭合时会伴随着一连串的抖动,这个抖动会使得按键输出的高低电平连续变化,而这并不是真正的按下按键,如果直接作为开关控制后续电路,就会造成电路的不稳定,因此,需要采用按键消抖。
机械按键按下时候有一个不稳定的抖动期,这个时间大概在20ms以内,我们可以利用这个20ms的抖动期,当检测到按键电平变化时20ms计数器重新计数,若计数器达到20ms,证明按键电平变化以后的20ms内没有再发生电平变化,可以认为是按键真正被按下,将此时的按键状态放入寄存器进而控制后续电路。

二、按键消抖程序实现(Verilog)

1.按键触发判断

  • 只要有按键状态变化,20ms计数器就应重新开始计数。而判断按键状态是否变化应该比较按键前后两个状态,由此采用移位寄存器,缓存按键前后的状态,再进行逻辑运算判断按键被按下还是松开。

注意:只要有按键被按下就要采用延时20ms消抖,同时按键全被松开也会对应按键电平的变化,仍然要采用消抖

代码如下:

wire key ; //用于按键触发判断
reg[3:0] key_r ; //缓存标志key的信息
assign key = key_h[3]&key_h[2]&key_h[1]&key_h[0] ;
always@(posedge sys_clk_i or negedge ext_rst_n)beginif(!ext_rst_n) key_r <= 4'b1111;else key_r <= {key_r[2:0],key}; //左移寄存器,最低位保存按键最新的状态
endwire key_neg = key_r[3] & ~key_r[2] ; //key_r[2]是现态,[3]是前一个状态,采用左移寄存器
wire key_pos = ~key_r[3] & key_r[2] ;//按键全部被释放

2.计数器模块实现

  • 由于FPGA系统时钟是50MHz,需要计数到20ms 20ms/20ns得到结果为1_000_000次,表示需要每一个时钟上升沿计数,从0开始计数,计数到999_999,二十进制换算,需要采用20bit的寄存器来保存计数次数。
  • 计数至20ms时应进行清零操作
//20ms计数,一旦出现按键按下或释放重新开始计数
reg[19:0]cnt ;
always@(posedge sys_clk_i or negedge ext_rst_n)beginif(!ext_rst_n) cnt <= 20'd0 ;else if(key_neg || key_pos ) cnt <= 20'd0 ;else if(cnt == 20'd999_999) cnt <= 20'd0 ;else cnt <= cnt + 20'd1 ;
end

3.按键状态更新

模块输入的按键值【key_h】状态表示未消抖前按键的状态,而控制后续电路的应该是消抖后的按键状态,因此需要设置一个4bit的寄存器,用于保存消抖后的状态。
同时,由于我们时利用按键前后的状态比较来判断按键是否被按下,所以需要有两个4bit的寄存器,分别保存前后状态。

  • 【key_press】用于表示按键是否被按下
reg[3:0]key_value[1:0] ;
always@(posedge sys_clk_i or negedge ext_rst_n)beginif(!ext_rst_n)beginkey_value[0] = 4'b1111; //保存最新的状态key_value[1] = 4'b1111;endelse beginif(cnt == 20'd999_999) key_value[0] = key_h ;key_value[1] <= key_value[0];end
end
wire[3:0}key_press ;
assign key_press = key_value[1] & ~key_value[0] ;

4.按键控制led亮灭

//led状态控制模块
always@(posedge sys_clk_i or negedge ext_rst_n)beginif(!ext_rst_n) led <= 4'b1111 ;else beginif(key_press[0]) led[0] <= ~led[0];if(key_press[1]) led[1] <= ~led[1];if(key_press[2]) led[2] <= ~led[2];if(key_press[3]) led[3] <= ~led[3];end
end

三、仿真测试文件编写

`timescale 1ns / 1ps
module sim_keyboard();
reg sys_clk_i ;
reg ext_rst_n ;
reg[3:0]key_h ;
wire[3:0]led ;
keyboard utt_keyboard(.sys_clk_i(sys_clk_i),.ext_rst_n(ext_rst_n),.key_h(key_h), //按键未按下时高电平,按下后低电平.led(led));
initial beginsys_clk_i = 1'b0 ;ext_rst_n = 1'b0 ;key_h = 4'b1111 ;#1000@(posedge sys_clk_i) ; #2 ;ext_rst_n = 1'b1 ;@(posedge sys_clk_i) ; #2 ;//模拟按键抖动key_h[0] = 1'b0 ;#1000_000  ;//1mskey_h[0] = 1'b1 ;#5_000_000  ;//5mskey_h[0] = 1'b0 ;#3_000_000  ;//3mskey_h[0] = 1'b1 ;#1_000_000 key_h[0] = 1'b0 ;#1000_000  ;//1mskey_h[0] = 1'b1 ;#5_000_000  ;//5mskey_h[0] = 1'b0 ;#3_000_000  ;//3mskey_h[0] = 1'b1 ;#3_000_000  ;//3mskey_h[0] = 1'b0 ;#50_000_000  ;//50mskey_h[0] = 1'b1 ;#30_000_000  ;//30mskey_h[0] = 1'b0 ;#50_000_000  ;//50mskey_h[0] = 1'b1 ;$finish ;
endalways #10 sys_clk_i = ~sys_clk_i ;endmodule

四、编译结果

  • 可以看到计数器计数到999_999,此时【key_h】的值为1110,【key_value[0]】值仍然为1111,在下一个时钟上升沿,消抖完成,【key_value[0]】会保存1110,表示按键key_h[0]被按下
  • 下一个时钟上升沿计数器清零,重新开始20ms计数,key_value[0]即为消抖完成后案件的现态,key_value[1]表示按键的前一个状态,【key_press[0]】值为1,表示按键被按下。
  • 测试文件模拟按键抖动过程,仿真结果可以看到当按键值【key_h】变化时,【key_pos】【key_neg】检测到边沿变化,但并不会引起【led】电平变化,说明消抖模块是有效的

    代码
    链接:https://pan.baidu.com/s/1euNaVxH-goOatb3lxpe4aQ
    提取码:mcuh

FPGA学习-Verilog实现独立按键消抖相关推荐

  1. Verilog实现独立按键消抖(状态机)

    本文参考小梅哥的独立按键消抖视频 1,实验原理: 这里是黑金开发板教程中的图,可以看出,按键未按下时的状态是高电平,按下为低电平.下边是小梅哥画的图解. 因为是机械按键,按下时候有一个不稳定的抖动期, ...

  2. verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)

    独立按键消抖设计与验证 本实验主要是为了锻炼状态机的思维模式以及熟练掌握TB的写法 本节主要收获了:define的用法,另外就是,顶层的input在TB中是reg的真正含义,其实就是把激励当做寄存器来 ...

  3. Verilog功能模块 —— 按键消抖

    一. 什么是按键消抖 按键消抖_百度百科 (baidu.com) 按键消抖通常的按键所用开关为机械弹性开关,当机械触点断开.闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断 ...

  4. FPGA VerilogHDL语言 数字钟 按键消抖

    1.描述 一个简单的基于FPGA的数字钟,语言用的是VerilogHDL,可以实现以下功能: 1. 数码管显示0-59(秒表) 2. 数码管显示:时-分-秒 3. 数码管显示时分秒并且可以设置时间(小 ...

  5. FPGA学习笔记---利用连续赋值语句延时功能实现按键消抖

    最近一直在学习FPGA,今天在学习延时语句时,发现了连续赋值的一个特点.在连续赋值语句中添加延时时,任何小于延迟值的输入变化都会被滤除而不会体现在输出上.比如  #10 B = A; 当A的变化小于1 ...

  6. 基于verilog按键消抖设计

    关于键盘的基础知识,我就以下面的一点资料带过,因为这个实在是再基础不过的东西了.然后我引两篇我自己的博文,都是关于按键消抖的,代码也正是同目录下project里的.这两篇博文都是ednchina的博客 ...

  7. Verilog中按键消抖检测的实现

    Verilog按键消抖是FPGA学习时的一个入门教程,为避免眼高手低,还是再次分析与记录一下.此处着重介绍按键消抖的基本原理,对按键消抖与检测的关键技术进行分析,并进行功能仿真. 一.按键消抖基本原理 ...

  8. 【Verilog HDL 训练】第 09 天(按键消抖)

    5月7日 按键防抖 1. 用verilog实现按键抖动消除电路,抖动小于15ms,输入时钟12MHz. 在编写Verilog代码之前,先分析下一些前提问题,首先是几个按键(1个,多个),我们以1个和三 ...

  9. 【 FPGA 】按键消抖与LED灯流动小实验

    记录一个小实验吧,实验的目的是仅仅是塞塞牙缝而已,没其他意思,很简单. 功能:拨码开关控制led灯工作与否,拨码开关为on,led灯工作,否则不工作:导航按键up和down,也就是独立按键而已,控制l ...

最新文章

  1. 被誉为「教科书」,牛津大学231页博士论文全面阐述神经微分方程,Jeff Dean点赞...
  2. 滑丝杠上的无触点感应行程开关 SN04-N
  3. opporeno3详细参数_vivox30和opporeno3哪个好 vivox30和opporeno3对比评测
  4. 最优化基础和机器学习优化
  5. 20172315 2017-2018-2 《程序设计与数据结构》第九周学习总结
  6. MOne︱基于词包的无监督多主题得分 练习题
  7. 【渝粤教育】国家开放大学2018年秋季 0734-21T出纳实务 参考试题
  8. 百度编辑器上传图片配置php,谁配置过百度编辑器ueditor1.4.3的图片上传路径?
  9. 在ie7中overflow:hidden失效问题及解决方案
  10. 用teamviewer控制内网计算机
  11. Atitit 调用另外语言的功能 目录 1. Waht 常见的语言java python js sql xml h5 c# php等之间的互相调用 1 2. 为什么需要互相调用why 1 3. 常
  12. C++ 基础 弱类型语言是指不需要进行变量/对象类型声明的语言。Python属于弱类型语言
  13. PageHelper关闭count语句优化
  14. python 头条视频_今日头条python视频消重赞
  15. echart4.0 map支持dataset实例
  16. python cookies是什么_Python获取cookie有什么用
  17. VM虚拟机ssh免密登录其他主机
  18. 密集预测任务的多任务学习综述
  19. JAVJ输出二进制数字
  20. Opencv inRang() 和HSV色彩空间表

热门文章

  1. C语言——选择控制结构 寻找中位数v1.0编写一个函数返回三个整数中的中间数。函数原型:int mid(int a, int b, int c);功能是返回a,b,c三数中大小位于中间的一个数。
  2. 被Win11系统恶心到了
  3. 为什么mydock会经常崩溃_MyDock4.9.4.1客户端下载-MyDock软件下载 - iefans下载
  4. 准确率、查准率、召回率
  5. 嵌入式物联网学习方法
  6. 如何为安卓程序设置启动页面(splash)?
  7. python迭代器问题
  8. Python迭代器、生成器、可迭代对象
  9. 【转】微信小程序模板消息无限制群发
  10. 数据结构与算法(较全)