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

【FPGA入门】第五篇、按键消抖

目录

第一部分、按键抖动现象

第二部分、消抖思路及代码

1、简单的按键消抖思路

2、实际按键消抖思路

3、实际按键消抖模块代码

第三部分、总结


第一部分、按键抖动现象

        只要学习过单片机的都会知道,按键在按下去和松开的那个瞬间都存在抖动,在单片机消除抖动最简单的方式就是延时

        在FPGA的开发过程中,按键也不是理想状态。所以在按下按键和松开按键的瞬间都是存在机械抖动的。

        这种抖动可分为前抖动(按下瞬间带来的抖动),后抖动(松开瞬间带来的抖动),如下图所示。

        无论是前抖动还是后抖动,持续时间大约是5~10ms。

第二部分、消抖思路及代码

1、简单的按键消抖思路

        如下图为最简单的按键检测思路。这种思路,在不考虑按键存在抖动的情况下,用寄存器打拍的方式(pipeline),将key延时一个时钟周期,变为key_old

        接着再通过检测key与key_old之间的信号差,来判断按键是否按下。

         实现代码如下:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN   : 大屁桃
// E-mail : 2624507313@qq.com
// File   : key_shift_led.v
// Create : 2023-04-14 13:58:37
// -----------------------------------------------------------------------------
module key_shift_led(input wire clk,input wire rst_n,input wire key1,output wire [3:0]led);
//寄存器打拍,延迟key一个时钟周期
reg key_old;
//led流水状态寄存器
reg [3:0]led_shift = 4'b0001;//获取key_old信号
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginkey_old <= 1'b1;endelse beginkey_old <= key1;end
end
//理想按键按下检测方式
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginled_shift <= 4'b0001;endelse if (key1 == 1'b0 && key_old == 1'b1) beginled_shift <= {led_shift[2:0],led_shift[3]};end
end
//led状态赋值
assign led = led_shift;endmodule

        这种简单的消抖方式存在以下问题:      

        有的时候,按下按键,会看到LED灯一次性跳过两个,或者三个,没有实现按一下,跳一下的功能。

2、实际按键消抖思路

        在消除抖动之后,如果检测到按键按下(低电平持续了5ms),那么就输出一个周期的单脉冲标志,来表示按键按下。

        这么做的原因:人在正常按下按键,松开按键,按键稳定的时间一般是大于五毫秒的。

        cnt_5ms:这个计数器在clk下计数,清零方式为key == 1,cnt_5ms == 5ms计数值

        stable_flag:保证press_flag有且仅有一个时钟周期的高电平。cnt_5ms这个计数器在,key == 0,cnt_5ms == 5ms计数值的时候翻转,清零为key == 1

如果不这样搞得话,那么stable_flag在稳定时间里面就会有多个高脉冲。

        press_flag:在cnt_5ms == 5ms计数值,stable_flag == 0的时候翻转。这样才是一个周期的单脉冲。

        实际按键检测的时序图如下图所示:

3、实际按键消抖模块代码

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN   : 大屁桃
// E-mail : 2624507313@qq.com
// File   : key_shift_led_elim.v
// Create : 2023-04-14 12:38:11
// -----------------------------------------------------------------------------
module key_shift_led_elim(input wire clk,input wire rst_n,input wire key1,output wire [3:0]led);
//变量
reg [17:0]cnt_5ms;//0~249,999表示5ms时间到了
reg stable_flag;
reg press_flag;
//保存led流水状态的寄存器
reg [3:0]shift_led = 4'b0001;//cnt_5ms毫秒计数器
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) begincnt_5ms <= 1'b0;endelse if(cnt_5ms == 'd249_999)begincnt_5ms <= 1'b0;endelse if (key1 == 1'b0) begincnt_5ms <= cnt_5ms + 1'b1;endelse begincnt_5ms <= 1'b0;end
end
//stable_flag在key == 0稳定到5ms后,一直拉高
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginstable_flag <= 1'b0;endelse if (key1 == 1'b0 && cnt_5ms == 'd249_999) beginstable_flag <= 1'b1;endelse if(key1 == 1'b1)beginstable_flag <= 1'b0;end
end
//press_flag按下的一个周期的脉冲
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginpress_flag <= 1'b0;endelse if (stable_flag == 1'b0 && cnt_5ms == 'd249_999) beginpress_flag <= 1'b1;endelse beginpress_flag <= 1'b0;end
end
//按下按键shift_led移位
always @(posedge clk or negedge rst_n) beginif (rst_n == 1'b0) beginshift_led <= 4'b0001;        endelse if (press_flag == 1'b1) beginshift_led <= {shift_led[2:0],shift_led[3]};//位置调换end
end
//led状态流水
assign led = shift_led;endmodule

第三部分、总结

        这篇博客介绍了FPGA检测按键消抖的两种方式,通过检测按键来控制LED的移动。最简单的检测方式带来的问题就是偶尔会出现不灵敏的现象;实际的消抖方式能很好解决按键抖动的问题。

        最后希望我的博客对你有帮助,有需要的小伙伴可以查看本专栏更多的往期文章👾👾👾

        FPGA的学习之旅_大屁桃的博客-CSDN博客

相关文章:

【FPGA入门】第五篇、按键消抖

目录 第一部分、按键抖动现象 第二部分、消抖思路及代码 1、简单的按键消抖思路 2、实际按键消抖思路 3、实际按键消抖模块代码 第三部分、总结 第一部分、按键抖动现象 只要学习过单片机的都会知道&#xff0c;按键在按下去和松开的那个瞬间都存在抖动&#xff0c;在单片…...

【MySql】MySql的事务基础篇

文章目录 CURD加控制什么是事物为什么会出现事务事务的版本支持事务的提交方式 CURD加控制 模拟一个买票系统的场景如下所示&#xff1a; MySQL注定会被多个客户端进行访问的&#xff0c;这个是肯定的&#xff0c;存储的都是数据&#xff0c;数据在上层可能有一个线程在用&…...

docker创建Ubuntu,Ubuntu创建桌面环境,本机使用VNC连接

题目&#xff1a;docker创建Ubuntu&#xff0c;Ubuntu创建桌面环境&#xff0c;本机使用VNC连接 文章目录 前言docker创建基于Ubuntu:20.04的容器使用ssh连接容器容器安装桌面环境本机电脑使用VNC连接测试用python来创建的ui能否显示坑参考 前言 为什么我想要用ubuntu的桌面环…...

理解redis的多线程和IO多路复用

参考资料 https://blog.csdn.net/TZ845195485/article/details/119745735 Redis单线程和多线程问题的背景 Redis里程碑版本迭代 Redis的单线程 主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取&#xff08;socket读&a…...

iOS 开发 | 自定义不规则 label

把我之前发布在简书的博客搬运过来。 目录 场景思路具体实现1. 自定义一个继承自UILabel的IrregularLabel2. 在初始化方法中进行相应初始化和设置3. 在layoutSubviews方法中进行路径的设置 最终效果箭头 label 场景 最近 App 改版&#xff0c;以下是截取的部分 UI 设计图&…...

client-go的Indexer三部曲之三:源码阅读

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 《client-go的Indexer三部曲》全部链接 基本功能性能测试源码阅读 本篇概览 本文是《client-go的Indexer三部曲》系列的终篇&#xff0c;主要任务是阅读和…...

收件地址解析成 省+市+区+详细地址的形式

项目中的源代码在我的GitHub&#xff1a;https://github.com/weitw/address-analyzer 先看效果&#xff1a; 如上图&#xff0c;address数输入的地址&#xff0c;Address对象是解析后的地址。可以支持逆推上一级&#xff0c;且支持地址白话解析。 一、项目介绍 1、解析规则 …...

数据结构与算法基础(青岛大学-王卓)(5)

叮叮咚咚&#xff0c;新一期来袭&#xff0c;我还在吃桃子&#xff0c;吃桃子&#xff0c;吃桃子。。。串和python的字符串差不多,数组和广义表像是python的list 文章目录 串(string) - 字符串概念及术语串的类型定义存储结构&#xff08;同线性表&#xff09;串的模式匹配算法…...

微信小程序开发入门学习01-TDesign模板解读

目录 1 使用模板创建小程序2 app.json3 页面布局总结 原来我们使用微信开发者工具&#xff0c;比较困难的是前端框架的选择上&#xff0c;官方也没有提供一套框架供我们使用&#xff0c;最近开发者工具已经提供了一套前端框架&#xff0c;后续我们开发的效率会因为使用模板提高…...

使用 Jetpack Compose 创建自定义的对话框(Dialog)

在 Jetpack Compose 中&#xff0c;对话框&#xff08;Dialog&#xff09;是一种常见的用户界面组件&#xff0c;用于展示重要的信息、确认操作或者收集用户输入。本篇博客将带你深入了解 Jetpack Compose 中的对话框&#xff0c;并展示如何创建自定义的对话框&#xff0c;以满…...

c++ auto学习笔记

一、auto的意义 在C11中赋予auto的意义是&#xff1a;在声明变量时&#xff0c;根据初始化表达式自动推断该变量的类型。声明函数时作为函数返回值的占位符&#xff08;用在函数返回类型后置的情况&#xff09;。 如 auto i 6; //auto推断为intauto func()->int //函数返…...

【随机种子初始化】一个神经网络模型初始化的大坑

1 问题起因和经过 半年前写了一个模型&#xff0c;取得了不错的效果&#xff08;简称项目文件1&#xff09;&#xff0c;于是整理了一番代码&#xff0c;保存为了一个新的项目&#xff08;简称项目文件2&#xff09;。半年后的今天&#xff0c;我重新训练这个整理过的模型&…...

翻过那座山——Gitlab流水线任务疑难之编译有子模块的项目指南

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不是…...

手机照片删除后如何恢复

在如今移动互联网和智能手机时代&#xff0c;拍摄照片已经成为了人们常见的一种生活方式&#xff0c;尤其是通过手机拍摄照片已经成为了许多人记录生活点滴、分享经验和表达情感等的必备工具。但是&#xff0c;随着手机照片量的激增&#xff0c;意外删除手机中珍贵照片的事件也…...

SpringBoot 线上服务假死,CPU 内存正常,什么情况?

背景 开发小伙伴都知道线上服务挂掉&#xff0c;基本都是因为cpu或者内存不足&#xff0c;出现GC频繁OOM之类的情况。本篇文章区别以上的情况给小伙伴们带来不一样的服务挂掉。 还记得哔哩哔哩713事故中那场诡计多端的0吗&#xff1f; 图片 对就是这个0&#xff0c;和本次事…...

kotlin从入门到精通之内置类型

基本类型 声明变量 val&#xff08;value的简写&#xff09;用来声明一个不可变的变量&#xff0c;这种变量在初始赋值之后就再也不能重新赋值&#xff0c;对应Java中的final变量。 var&#xff08;variable的简写&#xff09;用来声明一个可变的变量&#xff0c;这种变量在初始…...

实战指南:使用Spring Boot实现消息的发送和接收

当涉及到消息发送和接收的场景时&#xff0c;可以使用Spring Boot和消息中间件RabbitMQ来实现。下面是一个简单的示例代码&#xff0c;展示了如何在Spring Boot应用程序中创建消息发送者和接收者&#xff0c;并发送和接收一条消息。 首先&#xff0c;你需要进行以下准备工作 确…...

常用的数据结构——栈

目录 1、入栈 2、出栈 3、获取栈顶的元素 4、从栈中查找元素 栈是一种常见的数据结构&#xff0c;栈的特点是后进先出&#xff0c;就像我们叠盘子&#xff0c;拿走上面的盘子才能拿到下一个。java中的栈java.util.Stack是通过java.util.Vector实现的&#xff0c;所以底层都…...

C++完成淄博烧烤节管理系统

背景&#xff1a; 这次我们结合今年淄博烧烤做一个餐厅管理系统&#xff0c;具体需求如下&#xff0c;我们选择的是餐饮商家信息管理 问题描述&#xff1a; 淄博烧烤今年大火&#xff0c;“进淄赶烤”是大家最想干的事情&#xff0c;淄博烧烤大火特火的原因&#xff0c;火的…...

我心中的TOP1编程语言

目录 一、评选最佳编程语言时需要考虑哪些标准 &#xff08;一&#xff09;易用性 &#xff08;二&#xff09;执行效率 &#xff08;三&#xff09;语言功能特性 &#xff08;四&#xff09;工具生态环境 &#xff08;五&#xff09;开发者社区 二、不同编程语言的优点…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...