当前位置: 首页 > news >正文

18.按键消抖模块设计(使用状态机,独热码编码)

(1)设计意义:按键消抖主要针对的时机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子就断开。因而在闭合以及断开的瞬间会伴随有一连串的抖动,为了保证系统正确的识别到按键的开关,就必须对按键的抖动进行处理,这就是按键消抖。

(2)Verilog实现代码:

module key_filter(clk,reset_n,key_in,key_p_flag,key_r_flag,key_state);input clk;input reset_n;input key_in;output reg key_p_flag;output reg key_r_flag;output reg key_state;reg key_in1;reg key_in2;reg key_in3;reg [3:0]STATE;
//抖动时间往往小于20ms,20ms = 20_000_000ns = 20ns * 1_000_000;   需要一个20位的寄存器reg [19:0]cnt;reg en_cnt;wire podge;wire nedge;wire arrive_time_20ms;//状态设计parameter IDLE      = 4'b0001;parameter P_SHAKE   = 4'b0010;parameter DOWN      = 4'b0100;parameter R_SHAKE   = 4'b1000;//异步输入key_in信号的同步化————“打两拍”always@(posedge clk)beginkey_in1 <= key_in;key_in2 <= key_in1;end//上升沿、下降沿设计always@(posedge clk)key_in3 <= key_in2;assign podge = key_in2  &&  (!key_in3);assign nedge = (!key_in2)  &&  key_in3;//20ms计数器模块设计    always@(posedge clk or negedge reset_n)if(!reset_n)cnt <= 20'd0;else if(en_cnt &&(cnt == 20'd999_999))cnt <= 20'd0;else if(en_cnt)cnt <= cnt + 20'd1;else cnt <= 20'd0;//计满20ms信号设计           assign arrive_time_20ms = (cnt == 20'd999_999);//状态机主程序设计always@(posedge clk or negedge reset_n)if(!reset_n)beginkey_r_flag <= 1'd0;key_p_flag <= 1'd0;key_state  <= 1'd1;STATE      <= IDLE;endelse begincase(STATE)IDLE:beginkey_r_flag <= 1'd0;key_state  <= 1'd1;if(nedge)beginSTATE <= P_SHAKE;en_cnt <= 1'd1;endelse STATE <= STATE;endP_SHAKE:beginif(arrive_time_20ms)beginSTATE <= DOWN;en_cnt <= 1'd0;key_p_flag <= 1'd1;key_state <= 1'd0;endelse if(podge)beginSTATE <= IDLE;en_cnt <= 1'd0;endelse STATE <= STATE;  endDOWN:beginkey_p_flag <= 1'd0;key_state <= 1'd0;if(podge)beginSTATE <= R_SHAKE;en_cnt <= 1'd1;endelse STATE <= STATE;          endR_SHAKE:beginif(arrive_time_20ms)beginSTATE <= IDLE;en_cnt <= 1'd0;key_r_flag <= 1'd1;key_state  <= 1'd1;endelse if(nedge)beginSTATE <= DOWN;en_cnt <= 1'd0;endelse STATE <= STATE; enddefault:beginkey_r_flag <= 1'd0;key_p_flag <= 1'd0;key_state  <= 1'd1;STATE      <= IDLE;endendcaseendendmodule

(3)仿真文件代码:

`timescale 1ns / 1psmodule key_filter_tb;reg clk;reg reset_n;reg key_in;wire key_p_flag;wire key_r_flag;wire key_state;key_filter key_filter_inst(.clk(clk),.reset_n(reset_n),.key_in(key_in),.key_p_flag(key_p_flag),.key_r_flag(key_r_flag),.key_state(key_state));initial clk = 1'd1;always #10 clk = ~clk;initial beginreset_n <= 1'd0;key_in  <= 1'd1;#15;reset_n <= 1'd1;#2000;key_in <= 1'd0;#1500;key_in <= 1'd1;#20000;key_in <= 1'd0;#40_000_000;key_in <= 1'd1;#1000;key_in <= 1'd0;#200;key_in <= 1'd1;#1800;key_in <= 1'd0;#25000;key_in <= 1'd1;#30_000_000;$stop;endendmodule

(4)仿真波形分析:

http://www.lryc.cn/news/396527.html

相关文章:

  • 【Hec-HMS】第一期:模型简介及软件安装
  • 逻辑回归不是回归吗?那为什么叫回归?
  • Activity对象的部分常见成员变量
  • 量化交易策略:赌徒在股市会运用凯利公式(附python代码)
  • 信息系统项目管理师【一】英文选择题词汇大全(1)
  • 怎么判断自己是否适合学习PMP?
  • 最新的数据防泄密方案来袭!
  • Python数据处理之高效校验各种空值技巧详解
  • Spring Boot与RSocket的集成
  • UI Toolkit generateVisualContent的使用
  • 第十六章 ValidationPipe验证post请求参数
  • HippoRAG如何从大脑获取线索以改进LLM检索
  • 求函数最小值-torch版
  • 如何将HEVC格式的视频转换为无损、未压缩的MP4格式视频?
  • 自定义在线活动报名表单小程序源码系统 源代码+搭建部署教程 可二次定制开发
  • 数据分析入门指南:表结构数据(三)
  • 凌凯科技前五大客户依赖症加剧:研发费用率骤降,应收账款大增
  • 5 科大讯飞AI大赛:热力学定律的电池材料生产参数动态调控
  • 概论(二)随机变量
  • Apache AGE 安装部署
  • Python29 Tensorflow的基本知识和使用
  • Linux操作系统上用到的磁盘分区管理工具
  • Python数据结构的库之Fuk使用详解
  • 【STM32学习】cubemx配置,串口的使用,串口发送接收函数使用,以及串口重定义、使用printf发送
  • 复现MiDAS文章:文章数据和代码
  • 【Python专栏】Python的历史及背景介绍
  • web端已有项目集成含UI腾讯IM
  • IF不降反增!审稿速度,比我家网速还快!3本接受率高的医学期刊,赶紧码住!
  • 怎样把视频字幕提取出来?分享4个零门槛的字幕提取工具
  • PostgreSQL 里怎样解决多租户数据隔离的性能问题?