基于FPGA的按键消抖
基于FPGA的按键消抖
文章目录
- 基于FPGA的按键消抖
- 前言
- 一、按键状态机
- 二、按键消抖模块
- 1.模块框图
- 2.模块代码
- 2.模块仿真代码
- 三、总结(含文件)
前言
按键消抖属于一个经典问题了,放一张图
大概就是根据经验,如果按键在20ms内没有变化则判定为按下。
一、按键状态机
本次是参考小梅哥的文档使用状态机写的按键消抖,状态转移图如下
二、按键消抖模块
1.模块框图
其中 :key_pose是在按键按下时刻产生一个时钟周期的高电平。
key_nege是在按键抬起时刻产生一个时钟周期的高电平。
key_out 是在按键消抖后的实际状态。
2.模块代码
开发平台:Vivado 2018.3
仿真平台:Modusim SE-64 10.5
开发平台:ALINX AX7Z020
代码如下:状态机的是按照野火的新式两段式状态机格式编写的
`timescale 1ns / 1nsmodule key
#(parameter CNT_20MS_MAX = 1_000_000
)
(input wire sys_clk ,input wire sys_rst_n ,input wire key_in ,output reg key_pose , output reg key_nege , output reg key_out
);reg key_in_reg1;
reg key_in_reg2;wire key_in_pose;
wire key_in_nege;reg key_out_reg;reg cnt_en;
reg cnt_20ms_full;
reg [19:0] cnt_20ms;reg [3:0] state;
localparam IDLE = 4'b0001,DOWN_FILTER = 4'b0010,DOWN = 4'b0100,UP_FILTER = 4'b1000;
//将按键信号同步至系统时钟地域,同时打拍缓解亚稳态
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_in_reg1 <= 1'b1;elsekey_in_reg1 <= key_in;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_in_reg2 <= 1'b1;elsekey_in_reg2 <= key_in_reg1;
//捕获按键按下的上升沿,下降沿
assign key_in_nege = (~key_in_reg1)&&(key_in_reg2);
assign key_in_pose = (key_in_reg1)&&(~key_in_reg2);always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)cnt_20ms <= 20'd0;else if((cnt_20ms == CNT_20MS_MAX - 1'b1) && (cnt_en == 1'b1))cnt_20ms <= cnt_20ms;else if((cnt_20ms != CNT_20MS_MAX - 1'b1) && (cnt_en == 1'b1))cnt_20ms <= cnt_20ms + 1'b1;elsecnt_20ms <= 20'd0; //按键处于状态2、4时开启20ms定时器
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)cnt_en <= 1'b0;else if((state == DOWN_FILTER) || (state == UP_FILTER))cnt_en <= 1'b1;elsecnt_en <= 1'b0;//按键记满将标志置1
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)cnt_20ms_full <= 1'b0;else if(cnt_20ms == CNT_20MS_MAX - 2'd2) cnt_20ms_full <= 1'b1;elsecnt_20ms_full <= 1'b0;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)state <= IDLE;else case(state)IDLE : if(key_in_nege == 1'b1)state <= DOWN_FILTER;elsestate <= IDLE; DOWN_FILTER : if(cnt_20ms_full == 1'b1)state <= DOWN;else if(key_in_pose == 1'b1)state <= IDLE; elsestate <= DOWN_FILTER; DOWN : if(key_in_pose == 1'b1)state <= UP_FILTER;elsestate <= DOWN; UP_FILTER : if(cnt_20ms_full == 1'b1) state <= IDLE; else if(key_in_nege == 1'b1) state <= DOWN; else state <= UP_FILTER; default : state <= IDLE; endcase always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_out <= 1'b1;else if(state == DOWN)key_out <= 1'b0;else if(state == IDLE)key_out <= 1'b1; elsekey_out <= key_out;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_out_reg <= 1'b1;elsekey_out_reg <= key_out; always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_pose <= 1'b0;else key_pose <= ~key_out_reg & key_out;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0)key_nege <= 1'b0;else key_nege <= key_out_reg & ~key_out;endmodule
2.模块仿真代码
参考了野火的代码
`timescale 1ns / 1nsmodule tb_key();parameter CNT_1MS = 20'd19 , CNT_11MS = 21'd69 , CNT_41MS = 22'd149 , CNT_51MS = 22'd199 , CNT_60MS = 22'd249 ;reg sys_clk;
reg sys_rst_n;
reg key_in;wire key_pose;
wire key_nege;
wire key_out; key
#(.CNT_20MS_MAX(20'd25)
)
key_inst
(.sys_clk (sys_clk ) ,.sys_rst_n (sys_rst_n) ,.key_in (key_in ) ,.key_pose (key_pose ) , .key_nege (key_nege ) , .key_out (key_out ) );reg [21:0] tb_cnt;initial beginsys_clk = 1'b1;sys_rst_n <= 1'b0;key_in <= 1'b0;#20sys_rst_n <= 1'b1; endalways #10 sys_clk =~ sys_clk;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) tb_cnt <= 22'b0; else if(tb_cnt == CNT_60MS) tb_cnt <= 22'b0; else tb_cnt <= tb_cnt + 1'b1;always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) key_in <= 1'b1; else if((tb_cnt >= CNT_1MS && tb_cnt <= CNT_11MS) || (tb_cnt >= CNT_41MS && tb_cnt <= CNT_51MS)) key_in <= {$random} % 2; else if(tb_cnt >= CNT_11MS && tb_cnt <= CNT_41MS) key_in <= 1'b0; else key_in <= 1'b1;endmodule
三、总结(含文件)
工程文件点这里~~
提取码:bemh
黑金的板子到了,真滴帅,赶紧点个灯试试手。
打算基于黑金的板子,将以前做的仿真都重构下下。
但是最近事情有点多,进度缓慢,呜呜呜 >o<
此工程可以应用于实际项目,如果认为文章写的不错请点赞支持。
FPGA初学者,欢迎交流鸭。
基于FPGA的按键消抖相关推荐
- 【按键消抖】基于FPGA的按键消抖模块开发
1.软件版本 QUARTUSII8.1 Modelsim6.5d 2.系统源码 module tops(i_clk, //100Mi_rst, //系统复位功能,高电平复位,如果不使用这个角,那么一直 ...
- 【 FPGA 】按键消抖与LED灯流动小实验
记录一个小实验吧,实验的目的是仅仅是塞塞牙缝而已,没其他意思,很简单. 功能:拨码开关控制led灯工作与否,拨码开关为on,led灯工作,否则不工作:导航按键up和down,也就是独立按键而已,控制l ...
- FPGA编程按键消抖
FPGA按键消抖 编写思路 1.按键消抖的基本原理 2.代码原理 3.代码部分 4.仿真代码编写 5.仿真 6.总结 一.按键消抖的基本原理 按键消抖,按下,松开存在毛刺,主要为了消除毛刺.通过稳定后 ...
- verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)
独立按键消抖设计与验证 本实验主要是为了锻炼状态机的思维模式以及熟练掌握TB的写法 本节主要收获了:define的用法,另外就是,顶层的input在TB中是reg的真正含义,其实就是把激励当做寄存器来 ...
- FPGA实现按键消抖及短时间按键和长时间按键不同动作
module key_test2(clk, //时钟信号:50Mhzrst, //按键复位key, //用户按键led //LED0~LED2);//端口定义input clk;input rst;i ...
- [FPGA入门笔记](十):按键消抖实验
简介 今天购买了AXLINX AX7020的开发板,从今天开始每一个例程都要做文档记录,为自己加油. 本实验,基于ALINX AX7020开发板,芯片为xc7z020clg400-2.开发板输入时钟为 ...
- FPGA VerilogHDL语言 数字钟 按键消抖
1.描述 一个简单的基于FPGA的数字钟,语言用的是VerilogHDL,可以实现以下功能: 1. 数码管显示0-59(秒表) 2. 数码管显示:时-分-秒 3. 数码管显示时分秒并且可以设置时间(小 ...
- 基于verilog按键消抖设计
关于键盘的基础知识,我就以下面的一点资料带过,因为这个实在是再基础不过的东西了.然后我引两篇我自己的博文,都是关于按键消抖的,代码也正是同目录下project里的.这两篇博文都是ednchina的博客 ...
- FPGA学习笔记---利用连续赋值语句延时功能实现按键消抖
最近一直在学习FPGA,今天在学习延时语句时,发现了连续赋值的一个特点.在连续赋值语句中添加延时时,任何小于延迟值的输入变化都会被滤除而不会体现在输出上.比如 #10 B = A; 当A的变化小于1 ...
- stm32 工业按键检测_STM32单片机按键消抖和FPGA按键消抖大全
写在前面: 物联网STM32入门 - 直播课程 - 创客学院www.makeru.com.cn 按键去抖:由上图可以看出理想波形与实际波形之间是有区别的,实际波形在按下和释放的瞬间都有抖动的现象,抖 ...
最新文章
- JZOJ 5473. 【NOIP2017提高组正式赛】小凯的疑惑
- QT Media Error: DirectShowPlayerService::doRender: Unresolved error code 0x80040266
- redis安装与基本配置
- Pro*C/C++简单介绍
- jquery实现app开发闹钟功能_一款让你真正摆脱懒觉的“闹钟APP软件”
- cmd 批处理文件(.bat)文件的编写
- 如何查看电脑ip地址
- 机器学习sklearn-线性回归
- python中tmp什么意思_python中tmp
- 【异常】git提示Ask a project Owner or Maintainer to create a default branch
- php访问微信云数据库,第三方服务器php获取微信小程序云开发access_token和云数据库...
- 小程序设置整个页面的背景颜色
- Kafka offset 偏移量详解
- 图像处理基础和OpenCV常用接口
- 【小5聊】本地IP地址设置为任意域名访问
- 【机器学习算法面试题】四.深度神经网络中激活函数有哪些?
- 交换内存SWAP使用率90%
- mpv播放器 —— 一个免费的、开源的、跨平台的媒体播放器
- 使用keytool和openssl生成RSA公钥私钥和证书,
- 受控电源(SOC PWM调压SVB)计算工具CVC使用说明
热门文章
- SOUI使用总结知识汇总.
- 17SWFObject使用
- JDK10 新特性详解
- docker介绍与应用
- 资讯美国悬赏1000万美元追捕勒索黑客、能源行业成为网络钓鱼攻击“重灾区”|11月8日全球网络安全热点
- matlab有限元分析程序,matlab有限元分析与应用(书及源程序)
- linux git difftool,git difftool 详解
- 混合储能系统能量管理simulink仿真模型。 蓄电池和超级电容构成的混合储能系统能量管理控制策略
- Max Script|修改器篇
- obj 格式3D模型转 gltf 格式