有限状态机实现按键防抖动电路

简要
由于金属弹性形变的原因,按键/开关在状态切换过程中总是会有或多或少的抖动情况,有时这种抖动会导致电路误动作,甚至无法正常工作。比如在设置参数时,按一下“加 1”可能会加 4~5 个数;生活中常见的情况是鼠标单击变成了双击等。因此,在很多时候,输入电路的信号需要经过防抖动处理之后才会送到后级电路。
按键抖动的电压波形如图 1 如示,tjitter 是抖动时间,通常在 1ms~30ms 之间。

设计要求
用 Verilog HDL 设计一个按键防抖动电路,要求用有限状态机实现。防抖动电路的输入接开发板的拨动开关,输出接 1 位十进制计数译码显示电路的时钟输入,实现每拨动一次开关计数器加 1,多次测试不出现抖动现象。
状态定义

parameter IDLE = 4'b0001;//闲置状态
parameter key1 = 4'b0010;//按下按键存在抖动的状态
parameter key2 = 4'b0100;//按下按键的稳定状态
parameter key3 = 4'b1000;//松开按键存在抖动的状态

状态转化图

程序代码
顶层模块:

module TYXS(
input clk,//clk时钟信号,rst清零信号,低电平清零,key为输入信号
input rst,
input key,
output  key_out,//输出的防抖动之后的波形
output  [6:0]codeout
);
digital a(
key_out,
rst,
codeout);
key_sh b(
clk,
rst,
key,
key_out
);
endmodule

十进制译码器显示模块

module digital(key_out,rst,codeout);
input key_out,rst;
output reg[6:0]codeout;
reg[3:0] keyout10;//寄存器用于十进制译码器显示,每按一次按键计数器加一
always@(posedge key_out,negedge rst)//十进制译码器显示,原有波形上升沿触发,即每按一次按键计数器加一
beginif(!rst) keyout10 <= 4'd0;else beginif(keyout10==4'd9) keyout10 <= 4'd0;//置零else keyout10 <= keyout10 + 4'd1;end
end
always@(*)begincase(keyout10)
4'b0000: codeout<= 7'b1000000;  //0
4'b0001: codeout<= 7'b1111001;  //1
4'b0010: codeout<= 7'b0100100;  //2
4'b0011: codeout<= 7'b0110000;  //3
4'b0100: codeout<= 7'b0011001;  //4
4'b0101: codeout<= 7'b0010010;  //5
4'b0110: codeout<= 7'b0000010;  //6
4'b0111: codeout<= 7'b1111000;  //7
4'b1000: codeout<= 7'b0000000;  //8
4'b1001: codeout<= 7'b0010000;  //9endcase
end
endmodule

按键防抖动模块

module key_sh(
input clk,//clk时钟信号,rst清零信号,低电平清零,key为输入信号input rst,
input key,
output reg key_out//输出的防抖动之后的波形
);
reg cnt_en;    //控制计数信号工作状态的使能信号
reg [18:0] cnt;//设置一个计数信号
reg [3:0] ns;  //nextstate,状态信号parameter IDLE = 4'b0001;//闲置状态
parameter key1 = 4'b0010;//按下按键存在抖动的状态
parameter key2 = 4'b0100;//按下按键的稳定状态
parameter key3 = 4'b1000;//松开按键存在抖动的状态always@(posedge clk,negedge rst)//计数器
beginif(!rst) cnt <= 0;else if(cnt_en) cnt <= cnt + 1'b1;//计数器使能为1时,开始计数,否则清零else cnt <= 0;
end
always@(posedge clk,negedge rst)
beginif(!rst) beginns <= IDLE;cnt_en <= 0;key_out <= 0;endelse begincase(ns)IDLE:beginkey_out <= 1'b0;//初始输出波形为低电平if(key==1&&cnt_en==0) beginns <= key1;//满足条件后进入下一状态key1cnt_en <= 1'b1;//使能信号变为1,计数器开始工作endelsens <= IDLE;//不满足条件,回归初始状态endkey1:beginkey_out <= 1'b0;//按下按键时输出波形为低电平if(cnt >= 19'd50_0000&&key==1) //因为testbench中设置了时间单位为10ns时钟周期为20ns,而设置的抖动波形不超过10ms,所以这里计数50万次beginns <= key2;//满足条件后进入下一状态key2,即延时了10mscnt_en <= 1'b0;//使能信号变为0,计数器停止工作且清零endelse if (cnt >= 19'd50_0000&&key==0)//防止出现一按下又松开的情况beginns <= IDLE;//回归初始状态cnt_en <= 1'b0;//使能信号变为0,计数器停止工作且清零endelse ns <= key1;//不满足计数条件则保持当前状态endkey2:beginkey_out <= 1'b1;if(key==0&&cnt_en==0) beginns <= key3;//满足条件后进入下一状态key3cnt_en <= 1'b1;//使能信号变为1,计数器开始工作endelse ns <= key2;//不满足计数条件则保持当前状态endkey3:beginkey_out <= 1'b1;if(cnt >= 19'd50_0000&&key==0) beginns <= IDLE;//处理完成,回归初始状态cnt_en <= 1'b0;//使能信号变为0,计数器停止工作且清零endelse if (cnt >= 19'd50_0000&&key==1)//防止出现一松开又按下的情况beginns <= key2;//回归上一状态cnt_en <= 1'b0;//使能信号变为0,计数器停止工作且清零endelse ns <= key3;//不满足计数条件则保持当前状态enddefault :ns <= IDLE;endcaseend
end
endmodule

仿真结果

有限状态机实现按键防抖动电路相关推荐

  1. 【swjtu】数字电路实验5_按键防抖动

    一.实验目的 1. 学习有限状态机的设计. 2. 学习信号边沿抖动的消除方法. 二.基本实验内容 由于金属弹性形变的原因,按键 / 开关在状态切换 过程中总是会有或多或少的抖动情况,有时这种抖动会导致 ...

  2. 单片机_CT107D训练平台电路原理图\蓝桥杯训练板\输入输出模块\矩阵按键\蜂鸣器电路\继电器电路\LM386功率放大电路,驱动扬声器

    输入/输出模块 配置 4×4 键盘矩阵,其中四个按键可通过跳线配置为独立按键: 配置继电器.蜂鸣器: 配置功率放大电路,驱动扬声器. 1>4×4 键盘矩阵原理图如下: 图片中的按键电路可以切换成 ...

  3. 原理篇2、按键扫描电路与驱动程序

    目录 1.74HC595电路 引脚功能 电路连接 级联 2.按键矩阵原理 3.扫描驱动程序 引脚初始化 输出设置 扫描读取 3.参考资料 资料获取 . 1.74HC595电路 引脚功能 管脚序号 符号 ...

  4. 记录一个 三个io口控制四个LED灯和一个按键的电路和怎么检测

    昨天要写个底层程序 发现要控制四个led灯和一个按键,按键开始一直不能很好的检测, 后面论坛问人才搞好. 分时扫描: 前1-4驱动LED,5检测KEY 1,LED1输出高,LED2输出低,LED3输入 ...

  5. 有限状态机的嵌入式Linux按键驱动设计(转载)

    本文转载自边缘之火<有限状态机的嵌入式Linux按键驱动设计(转载)> 原文链接:  http://www.eccn.com/design_2010052509381340.htm 秦国栋 ...

  6. linux 薄膜键盘驱动,有限状态机的嵌入式Linux按键驱动设计

    0  引言 一般的按键驱动程序通常非常简单.在程序中一旦检测到按键输入口为低电平时,就采用软件延时10 ms后再次检测按键输入口.如果仍然是低电平则表示有按键按下,便转入执行按键处理程序:否则,当按键 ...

  7. c语言实现按键的抖动与消除,8051单片机实验2——按键识别(一)

    按键识别方法之一 1. 实验任务 每按下一次开关SP1,计数值加1,通过AT89S51 单片机的P1 端口的P1.0 到P1.3显示出其的二进制计数值. 2. 电路原理图 图2.1 按键识别方法一 3 ...

  8. Verilog设计实例(8)按键防抖设计之软件防抖

    博文目录 写在前面 正文 背景介绍及回顾 单个按键 单按键的其他设计版本 多个按键 写在最后 参考资料 交个朋友 写在前面 个人微信公众号: FPGA LAB 个人博客首页 注:学习交流使用! 正文 ...

  9. 单片机按键软硬件设计技巧!

    在单片机系统里,按键是常见的输入设备,在本文将介绍几种按键硬件.软件设计方面的技巧. 一般在按键的设计上,一般有四种方案. 一是GPIO口直接检测单个按键,如图1.1所示; 二是按键较多则使用矩阵键盘 ...

最新文章

  1. Red Hat Linux 挂载外部资源
  2. UITableViewCell自定义高度
  3. OpenCV bgfg分割的实例(附完整代码)
  4. Python nose单元测试框架的安装与使用
  5. 必须建筑师附体!像盖大楼那样打造数据即服务
  6. 【Navicat】查看1000行以后的内容
  7. 利用Python进行「基金投资组合优化」(一)
  8. 7-164 打印杨辉三角 (20 分)
  9. java url链接超时_Java HttpURLConnection超时和IO异常处理
  10. vue 浏览器地址是ip_Vue实战041:获取当前客户端IP地址详解(内网和外网)
  11. Arduino学习(一)蓝牙模板之JDY-16 BLE(1)
  12. Tungsten Fabric知识库丨更多组件内部探秘
  13. Microsoft HoloLens 技术解谜(下)
  14. 域名whois查询接口代码
  15. 关于pr的一些实用小知识
  16. ios客户端学习-被苹果开发者中心拒绝附件上传不上
  17. 服务器突然Out of memory的问题排查
  18. python输出最大的素数_python-最大素数
  19. 计算机技能队训练总结,足球队训练工作总结_
  20. [离散数学]集合论基础P_5:可数集合与不可数集合

热门文章

  1. 【Win10分区教程】
  2. 在京东工作8年的程序员,35岁被裁拿到30多万的赔偿,终于自由了
  3. WordPress链接推送插件:果果推送
  4. 【社区图书馆】JAVA开发与架构(携程架构实践)
  5. pandas关于查看库或依赖库版本的API原理
  6. Java日志技术是什么
  7. 装修公司获客渠道攻略
  8. 2、milk-v duo(CV1800B,C906内核)控制IO,点亮LED
  9. DIY 盒装与散装cpu
  10. android 和风天气 调用示例,Android中 GsonFormat插件解析Jason 数据+和风天气接口解析案例(示例代码)...