状态机finite-state machine学习笔记2——按键消抖初步(1)
状态机finite-state machine学习笔记2
现实生活中按键按下之后并不会是理想状态
这里引入按键消抖的状态机学习
按键消抖第一种写法
状态
未按下时空闲状态(IDLE)
按下抖动滤除状态(FILTER0)
按下稳定状态(DOWN)
释放抖动滤除状态(FILTER1)
/*
Clk为50_000_000的时钟
Rst_n为复位信号
key_in为按键输入
key_flag为按键的使能状态
key_state是按键状态标志
*/
//主模块输入输出部分
module key_filter(Clk,Rst_n,key_in,key_flag,key_state);input Clk;input Rst_n;input key_in;output reg key_flag;output reg key_state;localparam //独热码方式IDEL = 4'b0001,FILTER0 = 4'b0010,DOWN = 4'b0100,FILTER1 = 4'b1000;reg[3:0]state;reg[19:0]cnt;reg en_cnt; //使能计数寄存器
电平判断和寄存部分
//对外部输入的异步信号进行同步处理reg key_in_sa,key_in_sb;reg key_tmpa,key_tmpb;wire pedge,nedge;always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginkey_in_sa <= 1'b0;key_in_sb <= 1'b0;endelse begin //寄存两个电平变化状态key_in_sa <= key_in;key_in_sb <= key_in_sa; end//使用D触发器存储两个相邻时钟上升沿时外部输入信号
//(已经同步到系统时钟域中)的电平状态always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginkey_tmpa <= 1'b0;key_tmpb <= 1'b0;endelse beginkey_tmpa <= key_in_sb;key_tmpb <= key_tmpa; end
//产生跳变沿信号 ,分别为上升沿和下降沿assign nedge = (!key_tmpa) & key_tmpb;assign pedge = key_tmpa & (!key_tmpb);
计数和计数满部分
reg cnt_full;//计数满标志信号
always@(posedge Clk or negedge Rst_n)if(!Rst_n)cnt <= 20'b0;else if(en_cnt)cnt <= cnt + 1'b1;elsecnt <= 20'b0;always@(posedge Clk or negedge Rst_n)if(!Rst_n)cnt_full <= 1'b0;else if(cnt == 999_999)cnt_full <= 1'b1;elsecnt_full <= 1'b0;
这里需要说明一下,我自己的FPGA的系统晶振为50_000_000Hz,周期为20ns,但是按键的按下一般为20ms左右20_000_000ns,为晶振周期的1_000_000倍,而1_000_000的16进制为F4240,对应二进制20位,因此这里的cnt为20个位
主模块状态机部分
1.状态为IDLE时,若检测到下降沿状态,则进入FILTER0的下降沿过滤抖动状态,并且打开计数器使能信号,否则在IDLE中死等。
2.状态为FILTER0时,若20ms还没有结束就有上升沿,那么认为按键在抖动,重新回到IDLE状态(去检测到下降沿重新20ms的计时); 如果只有低电平,按键已经按下,key_state置为低电平0,key_flag为1(状态已切换)
3.进入DOWN状态之后检测状态不变化,key_flag置为0,在DOWN状态中死等;检测上升信号后,进入FILTER1的滤除抖动状态,并且将计数使能信号打开
4.类比FILTER0状态
always@(posedge Clk or negedge Rst_n)if(!Rst_n)beginen_cnt <= 1'b0;state <= IDEL;key_flag <= 1'b0;key_state <= 1'b1;endelse begincase(state)IDEL :beginkey_flag <= 1'b0;if(nedge)beginstate <= FILTER0;en_cnt <= 1'b1;endelsestate <= IDEL;endFILTER0:if(cnt_full)beginkey_flag <= 1'b1;key_state <= 1'b0;en_cnt <= 1'b0;state <= DOWN;endelse if(pedge)beginstate <= IDEL;en_cnt <= 1'b0;endelsestate <= FILTER0;DOWN:beginkey_flag <= 1'b0;if(pedge)beginstate <= FILTER1;en_cnt <= 1'b1;endelsestate <= DOWN;endFILTER1:if(cnt_full)beginkey_flag <= 1'b1;key_state <= 1'b1;en_cnt <= 1'b0;state <= IDEL;endelse if(nedge)beginen_cnt <= 1'b0;state <= DOWN;endelsestate <= FILTER1;default:begin state <= IDEL; en_cnt <= 1'b0; key_flag <= 1'b0;key_state <= 1'b1;endendcase endendmodule
状态机转移图
状态转移条件
状态机finite-state machine学习笔记2——按键消抖初步(1)相关推荐
- 有限状态机 FSM——Finite State Machine
有限状态机 1.状态机的结构 2.Mealy状态机和Moore状态机 3.用Verilog来描述可综合的状态机 实例 序列检测器 ADC采样控制电路 按键消抖 1.状态机的结构 其中F和G是两个有关状 ...
- FPGA---多按键消抖检测
在学习了单按键消抖方法后,按键消抖的关键点就是20ms的延时,这一点和单片机按键消抖的思路是一样的.但是FPGA的延时需要通过寄存器计数,这个是比较消耗内部资源的.如果要检测4个按键时,最简单的方法就 ...
- FSM(Finite State Machine,有限状态机)设计
有限状态机(Finite State Machine, FSM),根据状态机的输出是否与输入有关,可分为Moore型状态机和Mealy型状态机.Moore型状态机输出仅仅与现态有关和Mealy型状态机 ...
- 《计算机组成与CPU设计实验》5有限状态机的Verilog HDL描述(Finite State Machine,FSM)
多数控制逻辑都可以用有限状态机描述 状态机 状态机是组合逻辑和时序逻辑的特殊组合 时序逻辑用于存储状态 组合逻辑用于产生次态和产生输出 状态的数量是有限的,故称为有限状态机(Finite State ...
- Android官方实现的层次状态机Hierarchical State Machine源代码
Android官方内部的源代码中实现了一套层次状态机(Hierarchical State Machine),总共有三个代码文件:IState.java , State.java, StateMach ...
- 有限状态机FSM(Finite State Machine)及实现方式介绍(转)
原文:https://www.cnblogs.com/barrywxx/p/12860573.html 一.为什么引入有限状态机? 最近做一个项目,项目中很多实体(Entity),每个实体都有很多状态 ...
- 有限状态机FSM(finite state machine) 一
有限状态机FSM(finite state machine) 一 有限状态机又称有限自动状态机,它拥有有限数量的状态,每个状态代表不同的意义,每个状态可以切换到 零-多 个状态.任意时刻状态机有且只能 ...
- 证明与计算(7): 有限状态机(Finite State Machine)
什么是有限状态机(Finite State Machine)? 什么是确定性有限状态机(deterministic finite automaton, DFA )? 什么是非确定性有限状态机(nond ...
- 有限状态机FSM(finite state machine) 二
有限状态机FSM(finite state machine) 二 延续上一篇继续有限状态机 上一篇中的状态切换判断是在每一个状态类的 OnExecute 方法中各种 if else 硬编码逻辑 当状态 ...
- STM32学习笔记:按键实验
STM32学习笔记:按键实验 一.所使用的函数 1.时钟使能函数 RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState New ...
最新文章
- NVIDIA数据中心深度学习产品性能
- 第七课.Python面向对象(一)
- cmake 成功后, make 出现 No such file or directory 问题解决
- 2. getline()和get()
- 如何采用python语言绘制一条_如何使用matplotlib绘制一条线?
- 圣路易斯华盛顿大学计算机科学,圣路易斯华盛顿大学计算机科学专业入学要求是什么?...
- pom.xml配置详解
- volatile关键字及编译器指令乱序总结
- 英伟达自动驾驶技术:用于自动驾驶汽车的端到端深度学习
- java生成pdf表格_java生成pdf文件 --- Table
- JSON.stringify方法详解
- spyder指定python环境
- html5实现统计功能,基于HTML5的统计图表系统的设计与实现
- 第十二章 软件壳(四)(代码抽取型壳)
- Word中如何删除目录页的页码
- 客户端与服务器端交互原理(HTTP数据请求与HTTP响应)
- maven阿里镜像下载jar包报错
- 为什么要早点进入IT行业?
- nand flash多少次写_这个比QQ空间还古老的网站,是多少女孩的精神家园?
- 拯救动画卡顿之FLIP
热门文章
- [生活] 2015年终总结,2016开篇计划
- Google亲儿子 Nexus/Pixel 手机刷机Root之旅
- 前端项目,css样式获取到了,没能渲染页面
- react native+typescript创建移动端项目-(慕课网喜马拉雅项目笔记)-(一,项目的初始化配置)
- 导入grafana的dashboards模板
- 远程文件传输工具Filezilla
- html5张图片响应式自动轮播代码,利用jQuery实现响应式Banner图片轮播代码
- mysql编译参数详解_教你MySQL数据库的编译安装以及命令详解(5.7版本)
- lora信号测试小助手_LoRa技术——30个常见问题解答
- html视频播放 bootstrap,基于Bootstrap和jQuery的视频播放器插件