FPGA学习-Verilog实现独立按键消抖

这篇具有很好参考价值的文章主要介绍了FPGA学习-Verilog实现独立按键消抖。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

利用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)begin
	if(!ext_rst_n) key_r <= 4'b1111;
	else key_r <= {key_r[2:0],key}; //左移寄存器,最低位保存按键最新的状态
end

wire 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)begin
	if(!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的寄存器,分别保存前后状态。文章来源地址https://www.toymoban.com/news/detail-756578.html

  • 【key_press】用于表示按键是否被按下
reg[3:0]key_value[1:0] ;
always@(posedge sys_clk_i or negedge ext_rst_n)begin
	if(!ext_rst_n)begin
		key_value[0] = 4'b1111; //保存最新的状态
		key_value[1] = 4'b1111;
	end
	else begin
		if(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)begin
	if(!ext_rst_n) led <= 4'b1111 ;
	else begin
		if(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 begin
	sys_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  ;//1ms
	key_h[0] = 1'b1 ;
	#5_000_000  ;//5ms
	key_h[0] = 1'b0 ;
	#3_000_000  ;//3ms
	key_h[0] = 1'b1 ;
	#1_000_000 
	key_h[0] = 1'b0 ;
	#1000_000  ;//1ms
	key_h[0] = 1'b1 ;
	#5_000_000  ;//5ms
	key_h[0] = 1'b0 ;
	#3_000_000  ;//3ms
	key_h[0] = 1'b1 ;
	#3_000_000  ;//3ms
	key_h[0] = 1'b0 ;
	#50_000_000  ;//50ms
	key_h[0] = 1'b1 ;
	#30_000_000  ;//30ms
	key_h[0] = 1'b0 ;
	#50_000_000  ;//50ms
	key_h[0] = 1'b1 ;
	$finish ;
end

always #10 sys_clk_i = ~sys_clk_i ;

endmodule

四、编译结果

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

到了这里,关于FPGA学习-Verilog实现独立按键消抖的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • verilog实现滚动显示学号(含按键消抖)

    经过了前前后后将近十个小时的时间,总算能够正确上板并写完了最终的实验报告。花费了我大量时间的实验我觉得有必要记录并分享出来。声明: 本人写verilog的能力不强,看我花了这么多时间就知道了,如果代码有问题感谢指正,代码是在这位学长的基础上修改的 零时的

    2024年02月04日
    浏览(33)
  • 用verilog编写按键消抖代码

    本代码在按键按下和松开情况下均能消抖,消抖延时20ms(时钟频率为100MHz时)。 代码如下 module key3_led2( //from system input     input    clk,     input    rstn, //from external input to pl     input    ex_key1,        //按键从PL端输入 //from pl to ps     output    reg    pl_key1    //处理

    2024年02月02日
    浏览(44)
  • 基于vivado(语言Verilog)的FPGA学习(5)——跨时钟处理

    慢时钟到快时钟一般都不需要处理,关键需要解决从快时钟到慢时钟的问题,因为可能会漏信号或者失真,比如: 第一种办法是开环解决方案,也就是人为设置目标信号脉宽大于1.5倍的周期。但是容易和设计要求冲突 所以第二个大方法是闭环解决方案,也就是从改善同步方

    2024年02月03日
    浏览(49)
  • 基于vivado(语言Verilog)的FPGA学习(2)——zedboard开机测试和程序烧写

    终于找到之前写的部分了,在OneNote上,以后还是专注写在一个地方 ZedBoard 可以通过四个不同的方法烧写,这些方法是: USB-JTAG 这是默认的并且是最直接的烧写 ZedBoard 的方法 , 这只要通过 ZedBoard 工具包的 USB 到 micro-USB 连接线就可以直接完成。 传统 JTAG 板卡上有一个可用的

    2024年02月16日
    浏览(56)
  • FPGA/Verilog HDL/AC620零基础入门学习——第一个项目按键控制LED

    最近要考试了,所以我赶紧补习FPGA,我们用的是小梅哥的AC620开发板,软件是Quartus。推荐看这个视频教程:零基础轻松学习FPGA,小梅哥FPGA设计思想与验证方法视频教程 用按键控制LED灯的亮灭就是一个二选一多路器,两个IO,a、b,可以是高电平,也可以是低电平。 输入按键

    2024年02月05日
    浏览(57)
  • 【FPGA零基础学习之旅#10】按键消抖模块设计与验证(一段式状态机实现)

    🎉欢迎来到FPGA专栏~按键消抖模块设计与验证 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 🥝 模块设计: 🥝 按键消

    2024年02月12日
    浏览(44)
  • FPGA 驱动数码管动态显示(Verilog&Vivado)

    应用实例: (1)使用串口发送实现ACX720开发板时钟显示 本章将实现 FPGA 驱动数码管动态显示并提取出实现的电路结构,从电路结构入手编写代码,仿真对设计进行验证。最终板级调试时使用 Virtual Input/Output(VIO,虚拟输入/输出端口工具),输入需要显示的数据,数码管则显

    2023年04月12日
    浏览(57)
  • 【FPGA/verilog -入门学习4】verilog 实现多路脉冲计数

    设计一个脉冲计数器,其功能如下 输入脉冲:4路脉冲信号,分别对每路进行脉冲检测并计数 使能信号:高电平进行计数,低电平清零计数器 计数器:在使能信号高电平期间,对脉冲信号的上升沿进行检测并递增计数值 编写测试脚本,进行仿真验证 使用上一章的一路脉冲检

    2024年02月04日
    浏览(50)
  • FPGA学习——按键控制LED流水灯(附源码 无按键消抖版本)

    在博主的cyclone4开发板上一共有4个按键,本次实验的目的是为了实现每按下一次按键,都会使开发板上的4个LED灯切换一次状态,博主一共设计了四种状态,分别是: 按键 状态 按键1按下 自右向左的流水灯 按键2按下 自左向右的流水灯 按键3按下 四灯常亮 按键4按下 四灯闪烁

    2024年02月06日
    浏览(46)
  • 基于vivado+Verilog FPGA开发 — GT收发器

    代码规范:Verilog 代码规范_verilog代码编写规范-CSDN博客 开发流程:FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客   源码下载:GitHub - Redamancy785/FPGA-Learning-Record: 项目博客:https://blog.csdn.net/weixin_51460407 零、低速通信接口的缺陷 1、同步通信要求传输数据

    2024年04月17日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包