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

这篇具有很好参考价值的文章主要介绍了【FPGA入门】第五篇、按键消抖。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

第一部分、按键抖动现象

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

1、简单的按键消抖思路

2、实际按键消抖思路

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

第三部分、总结


第一部分、按键抖动现象

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

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

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

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

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

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

1、简单的按键消抖思路

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

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

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

         实现代码如下:

// -----------------------------------------------------------------------------
// 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的时候翻转。这样才是一个周期的单脉冲。

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

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

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博客文章来源地址https://www.toymoban.com/news/detail-500241.html

到了这里,关于【FPGA入门】第五篇、按键消抖的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 二、13【FPGA】按键消抖

    学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。 学习视频:是根据野火FPGA视频教程——第十六讲 https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3 按键常常作为系统复位信号和控制信号的外部输入,主要分为自锁按键、机械按键和薄膜按键等。开发

    2023年04月26日
    浏览(49)
  • FPGA学习-Verilog实现独立按键消抖

    利用verilog语言实现独立按键消抖,文章首先对按键抖动产生的原因、消抖原理进行简要解释;之后详细阐述各模块verilog语言实现方法;最后利用四个独立按键控制led亮灭,在vivado下进行源码设计与仿真。(完成程序代码附在文章结尾) 按键一般是机械弹性开关,由于机械触

    2024年02月04日
    浏览(39)
  • FPGA拾忆_(10):按键控制蜂鸣器_边沿检测_按键消抖

    1.硬件特征: 轻触式(回弹式)按键         略 蜂鸣器: 分为蜂鸣器按照结构原理不同可分为压电式蜂鸣器和电磁式蜂鸣器。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、 阻抗匹配器及共鸣箱、外壳等组成; 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组

    2024年04月10日
    浏览(41)
  • 单片机入门资料,按键消抖方式,按键怎么消抖

     1.什么是按键消我们先来看一下按键按下去的波形图   1.按键消抖原理 我们可以看到当按键按下的那一时刻和松开的时候有类似于锯齿的形状那就是按键抖动,这个抖动不是我们人为能控制得了的,所以我们只能对进行硬件消抖或者进行软件消抖.          上图中我们可以

    2024年02月08日
    浏览(41)
  • FPGA学习——按键控制LED流水灯(附源码 无按键消抖版本)

    在博主的cyclone4开发板上一共有4个按键,本次实验的目的是为了实现每按下一次按键,都会使开发板上的4个LED灯切换一次状态,博主一共设计了四种状态,分别是: 按键 状态 按键1按下 自右向左的流水灯 按键2按下 自左向右的流水灯 按键3按下 四灯常亮 按键4按下 四灯闪烁

    2024年02月06日
    浏览(47)
  • 【FPGA零基础学习之旅#10】按键消抖模块设计与验证(一段式状态机实现)

    🎉欢迎来到FPGA专栏~按键消抖模块设计与验证 ☆* o(≧▽≦)o *☆ 嗨 ~我是 小夏与酒 🍹 ✨ 博客主页: 小夏与酒的博客 🎈该系列 文章专栏: FPGA学习之旅 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏 📜 欢迎大家关注! ❤️ 🥝 模块设计: 🥝 按键消

    2024年02月12日
    浏览(45)
  • Vue基础第五篇

    keep-alive 可以让输入框内有的内容一致保持,不会因为切换而重置 一般情况下,编写完1个组件之后,组件的内容都是写死的,需要加数据 只能去组件中修改,扩展性很差 然后就出现了 插槽 这个概念,只需在组件中添加 slot/slot ,就可以在body的组件标签中添加内容 可以指定

    2024年02月08日
    浏览(39)
  • Mysql---第五篇

    A原子性由undo log日志保证,它记录了需要回滚的日志信息,事务回滚时撤销已经执行成功的sql C一致性由其他三大特性保证、程序代码要保证业务上的一致性 I隔离性由MVCC来保证 D持久性由内存+redo log来保证,mysql修改数据同时在内存和redo log记录这次操作,宕机的时候可 以从

    2024年02月07日
    浏览(44)
  • 初识Linux:第五篇

    😁本篇主要介绍Linux权限的相关知识👇 🤔在了解权限之前,先来了解一下Linux有哪些用户呢? Linux下的用户有两种, 超级用户 (root用户), 普通用户 (也就是你adduser的用户); windows: 在windows下的用户是 管理员用户( 超级用户)和 普通用户 ,与Linux下的差不多,但是Linux的权

    2024年02月05日
    浏览(35)
  • Arduino程序设计(四)按键消抖+按键计数

    本文主要介绍两种按键控制LED实验: 第一种是采用软件消抖的方法检测按键按下的效果; 第二种是根据按键按下次数,四个LED灯呈现不同的流水灯效果。 按键在按下时,由于机械和物理特定的原因,经常会产生一些开关变换,而这些变换会让程序误认为是短时间内进行了多

    2024年02月10日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包