15 ABC基于状态机的按键消抖原理与状态转移图

2024-02-12 08:28

本文主要是介绍15 ABC基于状态机的按键消抖原理与状态转移图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 基于状态机的按键消抖

1.1 什么是按键?

从按键结构图10-1可知,按键按下时,接点(端子)与导线接通,松开时,由于弹簧的反作用力,接点(端子)与导线断开。

从原理图10-2可知,按键按下时为低电平,未按下为高电平

1.2 为什么要消抖?

1.3 基于按键消抖的状态转移图

2. 写设计代码,仿真代码并仿真(未使用随机函数的测试)

1. 设计代码

module key_filter(clk,rstn,key,
//    key_p_flag,
//    key_r_flag,key_flag,key_state
);input clk;input rstn;input key;
//   output reg key_p_flag;
//   output reg key_r_flag;output reg key_flag;output reg key_state;//边沿检测reg [1:0] r_key;always@(posedge clk)r_key <= {r_key[0], key}; 
//    reg [1:0] r_key;    
//    always@(posedge clk)begin
//        r_key[0] <= key;
//        r_key[1] <= r_key[0]; 
//    endwire nedge_key;wire pedge_key;assign nedge_key = (r_key == 2'b10);assign pedge_key = (r_key == 2'b01);reg [1:0]state;reg [19:0] cnt;always@(posedge clk or negedge rstn)if(!rstn)beginstate <= 0;cnt <= 0;
//        key_p_flag <= 0;
//        key_r_flag <= 0;key_flag <= 0;key_state <= 1;endelsecase(state)0: begin
//            key_r_flag <= 0;key_flag <= 0;if(nedge_key == 1) beginstate <= 1;endelsestate <= 0;end 1:beginif((pedge_key == 1) && (cnt < 1000000 - 1))beginstate <= 0;cnt <= 0;endelse if((pedge_key == 0) && (cnt >= 1000000 - 1))beginstate <= 2;
//               key_p_flag <= 1'd1;key_flag <= 1'd1;key_state <= 0;cnt <= 0;endelsecnt <= cnt + 1'd1;end2:begin
//           key_p_flag <= 0;key_flag <= 0;if(pedge_key == 1)state <= 3;elsestate <= 2;end3:beginif((nedge_key == 1) && (cnt < 1000000 - 1))beginstate <= 2;cnt <= 0;endelse if((nedge_key == 0) && (cnt >= 1000000 - 1))beginstate <= 0;
//                key_r_flag <= 1;key_flag <= 1'd1;key_state <= 1;cnt <= 0;endelsecnt <= cnt + 1'd1;endendcaseendmodule

2. 仿真代码

`timescale 1ns / 1psmodule key_filter_tb();reg clk;reg rstn;reg key;
//    wire key_p_flag;
//    wire key_r_flag;wire key_flag;wire key_state;key_filter key_filter_inst(.clk(clk),.rstn(rstn),.key(key),
//        .key_p_flag(key_p_flag),
//       .key_r_flag(key_r_flag),.key_flag(key_flag),.key_state(key_state));initial clk = 1;always #10 clk = ~clk;initial beginrstn = 0;key = 1;#201;rstn = 1;#200;key = 1;#50000000;key = 0;#30000;key = 1;#30000;key = 0;#30000;key = 1;#30000;key = 0;#50000000;key = 1;#30000;key = 0;#30000;key = 1;#30000;key = 0;#30000;key = 1;#50000000;$stop;endendmodule

3. 仿真波形

 3. 基于verilog系统函数random的随机测试下的按键抖动(tb编写语法)

通过系统函数random产生一个随机的延迟值,来模拟真实情况下的延迟。

3.1 系统函数random的两个例子:

1. 产生一个[-(b+1): (b-1)]的随机数:$random% b;

2.产生一个[0: b-1]的随机数:{$random}% b;;

修改后的仿真代码:

`timescale 1ns / 1psmodule key_filter_tb();reg clk;reg rstn;reg key;
//    wire key_p_flag;
//    wire key_r_flag;wire key_flag;wire key_state;key_filter key_filter_inst(.clk(clk),.rstn(rstn),.key(key),
//        .key_p_flag(key_p_flag),
//       .key_r_flag(key_r_flag),.key_flag(key_flag),.key_state(key_state));initial clk = 1;always #10 clk = ~clk;reg [19:0] rand;initial beginrstn = 0;key = 1;#201;rstn = 1;#200;press_key(1);$stop;endtask press_key;input [2:0] seed;beginkey = 1;#20000000; repeat(5) beginrand = {$random(seed)} % 9999999; //产生0到9999999ns的延迟#rand key = ~key;endkey = 0;#40000000;repeat(5) beginrand = {$random(seed)} % 9999999; //产生0到9999999ns的延迟#rand key = ~key;endkey = 1;#40000000;endendtaskendmodule

4. 调试(产生多余38ns的原因)

 

这篇关于15 ABC基于状态机的按键消抖原理与状态转移图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/702154

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

Java发送SNMP至交换机获取交换机状态实现方式

《Java发送SNMP至交换机获取交换机状态实现方式》文章介绍使用SNMP4J库(2.7.0)通过RCF1213-MIB协议获取交换机单/多路状态,需开启SNMP支持,重点对比SNMPv1、v2c、v... 目录交换机协议SNMP库获取交换机单路状态获取交换机多路状态总结交换机协议这里使用的交换机协议为常