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

news2024/11/25 11:50:36

目录

第一部分、按键抖动现象

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

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) begin
    if (rst_n == 1'b0) begin
        key_old <= 1'b1;
    end
    else begin
        key_old <= key1;
    end
end
//理想按键按下检测方式
always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        led_shift <= 4'b0001;
    end
    else if (key1 == 1'b0 && key_old == 1'b1) begin
        led_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) begin
    if (rst_n == 1'b0) begin
        cnt_5ms <= 1'b0;
    end
    else if(cnt_5ms == 'd249_999)begin
        cnt_5ms <= 1'b0;
    end
    else if (key1 == 1'b0) begin
        cnt_5ms <= cnt_5ms + 1'b1;
    end
    else begin
        cnt_5ms <= 1'b0;
    end
end
//stable_flag在key == 0稳定到5ms后,一直拉高
always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        stable_flag <= 1'b0;
    end
    else if (key1 == 1'b0 && cnt_5ms == 'd249_999) begin
        stable_flag <= 1'b1;
    end
    else if(key1 == 1'b1)begin
        stable_flag <= 1'b0;
    end
end
//press_flag按下的一个周期的脉冲
always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        press_flag <= 1'b0;
    end
    else if (stable_flag == 1'b0 && cnt_5ms == 'd249_999) begin
        press_flag <= 1'b1;
    end
    else begin
        press_flag <= 1'b0;
    end
end
//按下按键shift_led移位
always @(posedge clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        shift_led <= 4'b0001;        
    end
    else if (press_flag == 1'b1) begin
        shift_led <= {shift_led[2:0],shift_led[3]};//位置调换
    end
end
//led状态流水
assign led = shift_led;

endmodule

第三部分、总结

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

玩转AI绘图 电脑配置怎么选?

大家好&#xff0c;我是权知星球&#xff0c;很多小伙伴留言想了解一下AI绘图相关知识&#xff0c;那么&#xff0c;想要玩转AI绘图&#xff0c;电脑配置该怎么选呢&#xff1f; 首先我们了解一下什么叫AI绘图&#xff1f; AI绘图指的是利用人工智能技术实现的自动绘图&#x…

小白到运维工程师自学之路 第三十七集 (mha高可用集群)

一、概述 MHA&#xff08;Master High Availability&#xff09;是一个开源的MySQL高可用性解决方案&#xff0c;它可以自动监测MySQL主节点的状态&#xff0c;并在主节点发生故障时自动将从节点提升为新的主节点&#xff0c;从而实现MySQL的高可用性。MHA集群通常由多个MySQL实…

C++基础(7)——类和对象(5)

前言 本文主要介绍C中的继承 4.6.1&#xff1a;继承和继承方式&#xff08;公有、保护、私有&#xff09; 4.6.2&#xff1a;继承中的对象模型&#xff0c;sizeof()求子类对象大小 4.6.3&#xff1a;子类继承父类后&#xff0c;两者构造和析构顺序 父类先构造、子类先析构 如…

一道SQL Server窗口函数的面试题

概要 本文介绍一道和SQL Server窗口函数相关的面试题&#xff0c;主要涉及窗口函数的原理和Framing参数的设置。 设计和实现 题目介绍 输入数据如下&#xff1a; 主要包括账户编号&#xff08;account_no&#xff09;&#xff0c;交易日期&#xff08;tran_date&#xff0…

Win10下旧移动硬盘设备USB3.0异常

旧USB3.0硬盘盒设备在WIN10下的异常情况&#xff0c;通过慢插入、快插入的方式进行工作模式的选择&#xff0c;其中在USB3.0的情况下&#xff0c;读写工作异常。 1、测试硬盘盒 商品名称&#xff1a;Iomega Prestige Disktop Hard Drive,USB 3.0 购买日期&#xff1a;2012年…

Ubuntu20.04显卡驱动安装的完整过程(超详细)

1、首先查看硬件&#xff1a;显卡是否安装 lspci | grep -i vga lspci | grep -i nvidia 注意&#xff1a;如果没显示显卡信息则看显卡是否安装好&#xff08;看下显卡风扇是否在转&#xff0c;图中是显卡位置&#xff09;&#xff0c;然后再执行上面的命令. 确定显卡安装没问…

Linux基础(一)—— 什么是Linux系统?和Windows区别在哪?常见的安装方式【新星计划Linux】

#2023 博客之星–城市之星领跑者活动开启# 文章目录 01 | Linux的特点02 | Linux 和 Windows03 | Linux的种类04 | Linux的安装方式 Linux 是一种自由和开放源代码的 Unix 操作系统&#xff0c;其内核是由林纳斯托瓦兹在1991年开始编写。Linux 操作系统采用了 GNU 项目的许多组…

【深度学习】4-3 误差反向传播法 - Affine/Softmax层的实现

Affine层 神经网络的正向传播中进行的矩阵的乘积运算(也就是Y np.dot(X, W) B)在几何学领域被称为“仿射变换”。因此&#xff0c;这里将进行仿射变换的处理实现为“Affine层”。 几何中&#xff0c;仿射变换包括一次线性变换和一次平移&#xff0c;分别对应神经网络的加权…

自由软件,自由社会之GNU 操作系统的初始公告

导读这是 GNU 工程的原始通告&#xff0c;由理查德斯托曼于 1983 年 9 月 27 日发表。纵观历史&#xff0c;可以发现 GNU 工程在很多地方都与这份初始通告有很多差异。比如实际是拖延到了 1984 年 1 月才开始。而自由软件的很多哲学理念也是数年之后才得以厘清。 From mit-vax!…

阿里云学生验证网页及申请认证流程

阿里云学生用户完成学生认证可以领取一台阿里云服务器&#xff0c;那么问题来了&#xff0c;阿里云学生验证申请入口​在哪&#xff1f;阿里云百科分享阿里云学生验证入口网页链接及学生认证全流程&#xff1a; 目录 阿里云学生验证入口及申请流程 打开学生验证申请入口 支…

周大福荣获2023亚洲零售大奖——年度珠宝零售商

由成立于1991年、服务于亚洲充满活力的零售业的行业杂志—《亚洲零售杂志》主办的“2023亚洲零售大奖”评选结果于6月15日揭晓&#xff0c;周大福珠宝集团凭借创新和卓越的表现荣获“2023亚洲零售大奖—年度珠宝零售商&#xff08;中国&#xff09;”&#xff0c;是中国唯一入榜…

产品经理面试常见的25个必问题(二)

14、举例分析你知道的几种商业模式和盈利模式&#xff1f; 先明确商业模式和盈利模式的不同。 1)、商业模式有很多种&#xff0c;但基本分为三类&#xff1a; ●以客户驱动的商业模式&#xff0c;多是代理大厂商产品为主&#xff0c;以营销客户赚差价和服务费为主&#xff1…

GPT提示词系统学习-第四课-好玩的角色指令-效果简直是YYDS了

开篇 各位奇思妙想的程序伙伴们,如果你还未加入GPT万能生成器的狂欢队伍,那现在正是时候!让我来带你短暂探访一下GPT惊艳的角色创建功能。嘘~让我们秘密派对开始! 这位万能生成器让人头疼的问题终于迎刃而解——GPT能为你吹气成猴!它帮你创作角色如同魔法一般。 首先,…

【玩转Docker小鲸鱼叭】虚拟化技术简介

什么是虚拟化技术&#xff1f; Docker 是一款基于容器虚拟化技术构建的软件&#xff0c;那到底什么虚拟化技术呢&#xff1f;在学习 Docker 之前&#xff0c;先简单了解下虚拟化技术。 虚拟化是云原生的实现基础&#xff0c;它能够帮助我们更加有效地利用物理计算机硬件。 虚…

2023年中级工程师职称认定、考试和评审有什么区别呢?

2023年中级工程师职称认定、考试和评审有什么区别呢? 人社部门中级工程师职称获得的渠道只有三种&#xff1a;认定、考试和评审这三种渠道&#xff0c;都可以拿到正规的中级职称&#xff0c;那么这几种有什么区别呢&#xff1f; 要说区别的话&#xff0c;启程别老师告诉你&…

python使用pyinstaller打包运行过程中莫名的被阻塞

问题描述 使用pyinstaller打包python代码命令 python -m PyInstaller -i logo.ico -F -p ./console -n scl_runner ./main.py运行之后会有一个终端&#xff0c;可以看到终端日志输出正常&#xff0c;多次远程调用也没有问题&#xff0c;死循环测试调用10万次也没有卡死 然…

2023 互联网大厂 Java 面试 1210 道题全解析

很多 Java 工程师的技术不错&#xff0c;但是一面试就头疼&#xff0c;10 次面试 9 次都是被刷&#xff0c;过的那次还是去了家不知名的小公司。 问题就在于&#xff1a;面试有技巧&#xff0c;而你不会把自己的能力表达给面试官。 应届生&#xff1a;你该如何准备简历&#x…

管理类联考——写作——素材篇——论说文——写作素材01—志篇:理想•信念

管理类专业学位联考 (写作能力) 论说文素材 01——志篇&#xff1a;理想信念 论文说材料: 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚韧不拔之志。 ——苏轼《晁错论》 一&#xff1a;道理论据 没有生活的理想&#xff0c;就没有理想的生活。 ——中国共…

C/C++入门秋招知识点八股文

1.C/C关键字 1.1 static&#xff08;静态&#xff09;变量 在C中&#xff0c;关键字static是静态变量&#xff1a; 静态变量只会初始化一次&#xff0c;然后在这函数被调用过程中值不变。在文件内定义静态变量&#xff08;函数外&#xff09;&#xff0c;作用域是当前文件&a…

在HTML语法中,用花括号{}括起来的内容是什么呢?

在HTML语法中&#xff0c;使用花括号{}括起来的内容通常表示占位符或模板语法&#xff0c;用于动态地插入或生成具体的内容。这种语法通常是由特定的模板引擎或框架提供&#xff0c;并在服务器端进行处理。 比如在某Django模板文件中&#xff0c;有如下的代码&#xff1a; &l…