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

相关文章

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

kotlin中的模块化结构组件及工作原理

《kotlin中的模块化结构组件及工作原理》本文介绍了Kotlin中模块化结构组件,包括ViewModel、LiveData、Room和Navigation的工作原理和基础使用,本文通过实例代码给大家... 目录ViewModel 工作原理LiveData 工作原理Room 工作原理Navigation 工

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente

MySQL的隐式锁(Implicit Lock)原理实现

《MySQL的隐式锁(ImplicitLock)原理实现》MySQL的InnoDB存储引擎中隐式锁是一种自动管理的锁,用于保证事务在行级别操作时的数据一致性和安全性,本文主要介绍了MySQL的隐式锁... 目录1. 背景:什么是隐式锁?2. 隐式锁的工作原理3. 隐式锁的类型4. 隐式锁的实现与源代码分析4

MySQL中Next-Key Lock底层原理实现

《MySQL中Next-KeyLock底层原理实现》Next-KeyLock是MySQLInnoDB存储引擎中的一种锁机制,结合记录锁和间隙锁,用于高效并发控制并避免幻读,本文主要介绍了MySQL中... 目录一、Next-Key Lock 的定义与作用二、底层原理三、源代码解析四、总结Next-Key L