按键消抖(Verilog&Vivado)

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

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

按键作为基本的人机输入接口,由于其机械特性,在按键按下或松开的时候,都是会有抖动的。按键小豆的方式有很多。我的方法是通过计时来消抖,通过一个计数器,当按键输入有变化时,计数器清零,否则就累加,直到加到一个预定值,就认为按键稳定,输出按键值,这样就得到了没有抖动的按键值。


提示:以下是本篇文章正文内容,下面案例可供参考

一、按键消抖原理

普通按键的硬件示意图如下图所示。
c语言按键消抖,FPGA代码分享,fpga开发,vscode

按键结构示意图中可以看到按键存在一个反作用弹簧,因此当按下或者松开时均会产生额外的物理抖动,物理抖动便会产生电平的抖动。在按键从按下再到松开的过程中,其电平变化如下图所示,上为理想波形输出,下为实际波形输出。
c语言按键消抖,FPGA代码分享,fpga开发,vscode
上图中,产生的抖动次数以及间隔时间均是不可预期的,这就需要通过滤波来消除抖动可能对外部其他设备造成的影响。一般情况下抖动的总时间会持续 20ms 以内。这种抖动,可以通过硬件电路或者逻辑设计的方式来消除,也可以通过软件的方式完成。其中硬件电路消除抖动适用于按键数目较少的场合

二、状态机实现按键消抖

对于单按键的消抖模块,其接口如下图所示,接口声明功能描述如下:
c语言按键消抖,FPGA代码分享,fpga开发,vscode
各模块功能描述:
c语言按键消抖,FPGA代码分享,fpga开发,vscode
状态图如下:
c语言按键消抖,FPGA代码分享,fpga开发,vscode

三、Verilog代码实现

代码如下(示例):

module key_filter(
    Clk,
    Reset_n,
    Key,
//    Key_P_Flag,
//    Key_R_Flag,
    Key_Flag,
    Key_State
);
    input Clk;
    input Reset_n;
    input Key;
//    output reg Key_P_Flag;
//    output reg Key_R_Flag;
    output Key_Flag;
    output reg Key_State;
    
    reg Key_P_Flag;
    reg Key_R_Flag;
    
    assign Key_Flag = Key_P_Flag | Key_R_Flag;
    
    reg [2:0] r_Key;   //防止亚稳态用三个移位寄存器
    always@(posedge Clk)
        r_Key <= {r_Key[1:0],Key};
        
//    always@(posedge Clk)begin
//        r_Key[0] <= Key;  
//        r_Key[1] <= r_Key[0]; 
//        r_Key[2] <= r_Key[1]; 
//    end 

    wire pedge_key;
    assign pedge_key = (r_Key[2:1] == 2'b01);
    wire nedge_key;
    assign nedge_key = (r_Key[2:1] == 2'b10);
    
    reg [19:0]cnt;
    
    reg [1:0]state;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)begin
        state <= 0;
        Key_R_Flag <= 1'b0;
        Key_P_Flag <= 1'b0;
        cnt <= 0;
        Key_State <= 1;
    end
    else begin
        case(state)
            0:
                begin
                    Key_R_Flag <= 1'b0;
                    if(nedge_key)
                        state <= 1;
                    else
                        state <= 0;
                end
            
            1:
                if((pedge_key)&&(cnt <1000000 -1))begin
                    state <= 0;
                    cnt <= 0;
                end
                else if(cnt >= 1000000 -1)begin
                    state <= 2;
                    cnt <= 0;
                    Key_P_Flag <= 1;
                    Key_State <= 0;
                end
                else begin
                    cnt <= cnt + 1'b1;
                    state <= 1;
                end
                
            2:
                begin
                    Key_P_Flag <= 0;
                    if(pedge_key)
                        state <= 3;
                    else
                        state <= 2;
                 end
                    
            3:
                if((nedge_key)&&(cnt <1000000 -1))begin
                    state <= 2;
                    cnt <= 0;
                end
                else if(cnt >= 1000000 -1)begin
                    state <= 0;
                    cnt <= 0;
                    Key_R_Flag <= 1'b1;
                    Key_State <= 1;
                end
                else begin
                    cnt <= cnt + 1'b1;
                    state <= 3;               
                end
        endcase   
    end

endmodule


【注】:上述代码注释处采用三个移位寄存器防止亚稳态产生(触发器在时钟上升沿来临时对数据进行采样,产生对应的输出。但是实际器件无法瞬时完成数据采样这一过程,需要数据在时钟沿前后均稳定一定时间)具体可参考:亚稳态现象

四、TB文件

代码如下(示例):

`timescale 1ns / 1ps

module key_filter_tb2();

    reg Clk;
    reg Reset_n;
    reg Key;
//    wire Key_P_Flag;
//    wire Key_R_Flag;
    wire Key_Flag;
    wire Key_State;    
    
    key_filter key_filter(
        Clk,
        Reset_n,
        Key,
//        Key_P_Flag,
//        Key_R_Flag,
        Key_Flag,
        Key_State
    );
    
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        Key = 1;
        #201;
        Reset_n = 1;
        #3000;
        press_key(2);
        $stop;   
    end
    
    
    
    reg [31:0]rand;
    
    task press_key;
        input [3:0]seed;
        begin
            Key = 1;
            #20000000;
            repeat(5)begin
                rand = {$random(seed)} % 10000000;//(0,9999999)
                #rand Key = ~Key;
            end
            Key = 0;
            #40000000;
            
            repeat(5)begin
                rand = {$random(seed)} % 10000000;//(0,9999999)
                #rand Key = ~Key;
            end
            Key = 1;
            #40000000;           
        end
    endtask
    
endmodule

五、仿真波形展示

c语言按键消抖,FPGA代码分享,fpga开发,vscode
【附件:】链接:https://pan.baidu.com/s/1fZESYFREq6r3kTjIeDXlXA?pwd=vj42
提取码:vj42文章来源地址https://www.toymoban.com/news/detail-716547.html

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

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

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

相关文章

  • FPGA按键消抖

    按键是输入设备,一般来说,按键在没有按下的时候是高电平;当按键按下的时候,为低电平。 在 DE2-70 User Manual 中 Each switch provides a high logic level (3.3 volts) when it is not pressed, and provides a low logic level (0 volts) when depressed. Since the pushbutton switches are debounced, they are appropriate for use

    2024年02月15日
    浏览(52)
  • 基于FPGA的按键消抖

    按键抖动:按键抖动通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。当按下一次按键,可能在A点检测到一

    2024年02月16日
    浏览(52)
  • 二、13【FPGA】按键消抖

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

    2023年04月26日
    浏览(48)
  • 【FPGA入门】第五篇、按键消抖

    目录 第一部分、按键抖动现象 第二部分、消抖思路及代码 1、简单的按键消抖思路 2、实际按键消抖思路 3、实际按键消抖模块代码 第三部分、总结         只要学习过单片机的都会知道,按键在按下去和松开的那个瞬间都存在抖动,在单片机消除抖动最简单的方式就是 延

    2024年02月11日
    浏览(43)
  • 基于vivado(语言Verilog)的FPGA学习(5)——跨时钟处理

    慢时钟到快时钟一般都不需要处理,关键需要解决从快时钟到慢时钟的问题,因为可能会漏信号或者失真,比如: 第一种办法是开环解决方案,也就是人为设置目标信号脉宽大于1.5倍的周期。但是容易和设计要求冲突 所以第二个大方法是闭环解决方案,也就是从改善同步方

    2024年02月03日
    浏览(50)
  • 用verilog编写按键消抖代码

    本代码在按键按下和松开情况下均能消抖,消抖延时20ms(时钟频率为100MHz时)。 代码如下 module key3_led2( //from system input     input    clk,     input    rstn, //from external input to pl     input    ex_key1,        //按键从PL端输入 //from pl to ps     output    reg    pl_key1    //处理

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

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

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

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

    2024年02月06日
    浏览(47)
  • 基于vivado(语言Verilog)的FPGA学习(2)——zedboard开机测试和程序烧写

    终于找到之前写的部分了,在OneNote上,以后还是专注写在一个地方 ZedBoard 可以通过四个不同的方法烧写,这些方法是: USB-JTAG 这是默认的并且是最直接的烧写 ZedBoard 的方法 , 这只要通过 ZedBoard 工具包的 USB 到 micro-USB 连接线就可以直接完成。 传统 JTAG 板卡上有一个可用的

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

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

    2024年02月12日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包