ZYNQ——按键消抖实验

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


原理简介

按键作为基本的人机输入接口,在很多电子设计中都是比较常见的,但是由于其机械特性,在按键按下或者松开的时候,按键的输入值是有抖动的。按键的抖动是其固有特性,因此无论按键按下或松开的多么平稳,按键的抖动也是难以消除的。本文通过FPGA计数(计时)来达到按键消抖的目的。
计数的基本原理是:当按键的输入发生变化时,计数器就清零,判断按键的输入是否发生变化是通过两级D触发器的异或实现的。如果按键的输入没有发生变化,那么计数器就累加,直至累加到一个预定值,这个预定值是通过时间和时钟的频率确定的。计数器累加到这个预定值之后,就认为按键的输入已经稳定,可以输出,因此就得到了没有抖动的按键值。
按键消抖的示意图如下图所示。
ZYNQ——按键消抖实验,zynq,zynq,Vivado


软件仿真

在进行板上验证之前,先在Vivado软件中编写代码进行仿真,因为仿真的速度比较快,这样可以提高我们的效率。
仿真用到的设计源代码如下。

module key_anti_shake(
    input clk,
    input rst,
    input key_in,
    output reg key_out
    );

reg [3:0] count;
reg [3:0] count_next;
reg D1,D2;  //两级D触发器
wire add_flag;  //计数标志位
wire q_reset;
reg key_out_d;  

assign q_reset = (D1^D2);   //通过异或两级D触发器的值判断按键的变化
assign add_flag = ~(count == 4'd10);  //为1时,count可以继续加1;为0时,按键稳定,可输出

always@(q_reset,add_flag,count)
begin
    case({q_reset,add_flag})
        2'b00: count_next <= count;
        2'b01: count_next <= count + 1;
        default: count_next <= 4'b0000;  //如果q_reset=1就说明两级D触发器结果不一样,肯定不稳定
    endcase
end

always@(posedge clk or posedge rst)
begin
    if(rst == 1'b1) 
    begin 
        D1 <= 1'b0; 
        D2 <= 1'b0; 
        count <= 4'b0000; 
    end 
    else 
    begin 
        D1 <= key_in; 
        D2 <= D1; 
        count <= count_next; 
    end
end

always@(posedge clk or posedge rst)
begin
    if(rst == 1'b1) 
        key_out <= 1'b1;
    else if(count == 4'd10)
        key_out <= D2;
    else
        key_out <= key_out;
end

always@(posedge clk or posedge rst)
begin
    if(rst == 1'b1) 
    begin
        key_out_d <= 1'b1;
    end
    else
    begin
        key_out_d <= key_out;
    end
end

endmodule

仿真测试代码如下。

`timescale 1ns / 1ps
module key_anti_shake_sim();
reg clk;
reg rst;
reg key_in;
wire key_out;

initial
begin
    clk = 0;
    rst = 0;
    key_in = 1;
    #100
    key_in = 0;
    #100
    key_in = 1;
    #100
    key_in = 0;
    #600
    key_in = 1;
end

always #10 clk =~clk;
key_anti_shake uut_key_anti_shake(
    .clk(clk),
    .rst(rst),
    .key_in(key_in),
    .key_out(key_out)
);
endmodule

仿真输出结果如下图所示。
ZYNQ——按键消抖实验,zynq,zynq,Vivado
可以看到,首先是两级D触发器的不同使得q_reset变化,因此激活了重新计数,当计数到指定的数时,如果按键输入还没有发生变化,则认为按键的输入已经稳定,可以将其值输出。按键消抖实验的重点其实就是两级D触发器的输出值,如果在计数没到指定值时,两级D触发器输出有变化会使得 q_reset=1,而 q_reset=1的结果就是计数要从0重新开始,也就是说,要输出稳定的按键输入值,按键的值必须稳定持续指定的时间长度才可以。


板上验证

上面的代码中为了仿真方便,计数设计的比较小,在开发板上验证时,为了使按键消抖的效果明显,我在程序中将稳定的时间设置为1秒,这样就能够更清楚的看到,LED在按键触发1秒之后进行响应,也就是LED动作滞后按键1秒钟。
在开发板上验证使用的代码如下。

`timescale 1ns / 1ps

module key_anti_shake(
    input clk,
    input rst,
    input key_in,
    output key_out
    );

reg [25:0] count;
reg [25:0] count_next;
reg D1,D2;
wire add_flag;
wire q_reset;
reg key_out_d;

assign q_reset = (D1^D2); //judge whether the level change through xor
assign add_flag = ~(count == 26'd50_000_000);  //延迟1s

always@(q_reset,add_flag,count)
begin
    case({q_reset,add_flag})
        2'b00: count_next <= count;
        2'b01: count_next <= count + 1;
        default: count_next <= 26'd0;  //如果q_reset=1就说明两级D触发器结果不一样,肯定不稳定
    endcase
end

always@(posedge clk or negedge rst)
begin
    if(rst == 1'b0) 
    begin 
        D1 <= 1'b0; 
        D2 <= 1'b0; 
        count <= 26'd0; 
    end 
    else 
    begin 
        D1 <= key_in; 
        D2 <= D1; 
        count <= count_next; 
    end
end

always@(posedge clk or negedge rst)
begin
    if(rst == 1'b0) 
        key_out_d <= 1'b1;
    else if(count == 26'd50_000_000)
        key_out_d <= D2;
    else
        key_out_d <= key_out_d;
end

assign key_out = key_out_d;
endmodule

引脚分配如下图所示。
ZYNQ——按键消抖实验,zynq,zynq,Vivado
把比特流文件下载到开发板上验证时结果一直不正确,后来才发现我是在仿真代码的基础上修改的,而仿真代码中的复位是高电平有效,而我正好也给复位分配了一个按键引脚,而按键在不按下时就是高电平,因此,开发板上电后就一直在复位状态,除非按下复位按键,所以我把代码中的复位改为了低电平有效,重新生成比特流文件,下载到开发板验证。
按键消抖实验的开发板验证结果如下面动图所示。
ZYNQ——按键消抖实验,zynq,zynq,Vivado
可以看到,持续按下开发板上的 PL KEY1 按键1秒后,对应的 PL LED1 亮,松开按键1秒后,PL LED1 灭,因此,按键消抖的功能实现了!在实际应用中,按键消抖用不了这么长时间,我这里是为了演示的结果更加明显,一般延时大概几十毫秒就可以,其中,要延时的时间(以秒为单位)和计数之间的关系为:计数值 = 要延时的时间 × 频率。
比如在 50MHz 系统中延时 20ms, 计数值 = 20 × 1 0 − 3 × 50 × 1 0 6 = 1 0 6 计数值 = 20 × 10^{-3} × 50 × 10^6 = 10^6 计数值=20×103×50×106=106


以上就是ZYNQ——按键消抖实验的全部内容了!
参考资料:
ZYNQ 开发平台 FPGA 教程 AX7020文章来源地址https://www.toymoban.com/news/detail-736914.html

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

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

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

相关文章

  • ZYNQ-XC7Z020 JTAG 连接不上 Vivado

    平台: 【ALINX黑金开发板,板载JTAG】 【Vivado 2017.4】 最近项目需要使用到FPGA,没接触过被迫学习,第一关就遇到了困难。 具体情况: Vivado   Auto Connect 连接不上板子。 解决: 运行安装目录下 install_digilent.exe 程序。 G:XilinxVivado2017.4dataxicomcable_driversnt64digilentinstall_di

    2024年02月21日
    浏览(35)
  • ZYNQ-Linux开发之(三)Vivado SDK使用,裸机开发调试,不带linux

    生成bit文件时候的开发和调试需要使用SDK,导出工程到SDK: 包含bit文件,点击OK:  工程目录下会新增一个.sdk的目录: 启动SDK: 使用SDK进行调试,SDK中,新建应用工程,选择File-New-Application Project: 在弹出的窗口中,输入Project name,单击Next: 在弹出的窗口中,默认选择He

    2024年02月10日
    浏览(43)
  • ZYNQ实验--PDM波形生成

      将信号的振幅变化按比例地变换成脉冲宽度的变化,得到脉冲宽度调制(PDM)。详细的原理理论可以参考该文:文献阅读–Pulse-Width Modulation,本文主要介绍PDM的FPGA实现,PDM的生成方式很多具体形式根据需求会有所不同 实验设备: ZYNQ7020   早期的PDM信号通过比较器生成,通

    2024年03月16日
    浏览(26)
  • ZYNQ——锁相环(PLL)实验

    ZYNQ开发板上只有一个50MHz的时钟输入,如果要用到其他频率的时钟,就需要通过FPGA芯片内部集成的PLL(Phase Locked Loop,锁相环)来分频或者倍频实现。 一个复杂的系统往往需要多个不同频率、不同相位的时钟信号,所以FPGA芯片中的PLL的数量也是衡量FPGA芯片性能的重要指标。在

    2024年02月10日
    浏览(46)
  • ZYNQ实验 基于LWIP的UDP传输实验

      LWIP是嵌入式设备中较为常用的TCP/IP协议栈,本文将使用UDP协议传输较大的txt文件并写入PS端的DDR中,实验对文件传输的速率和准确率要求不高因此调用简单的UDP协议即可。 实验难点: LWIP的pbuf的理解。 对UDP接收回调函数的使用。 如果不知道如何创建和使用SDK可以参考该

    2024年02月04日
    浏览(27)
  • ZYNQ学习笔记——高速ADDA实验

    D/A: 就是将_数字量转换成模拟量_ A/D: 就是将_模拟量转换成数字量_,模拟量可以是电压电流等电信号也可以是声、光、压力、湿度等连续变化的非电物理量,但是这些非电物理量最终都要通过一定手段转换成电信号 分类 DAC 网络权电阻DAC(本次实验所用类型) 倒梯形电阻网络

    2024年02月06日
    浏览(28)
  • ZYNQ之FPGA 片内ROM读写测试实验

    FPGA本身是SRAM架构的,断电之后程序就会消失,那么如何利用FPGA实现一个ROM呢,我们可以利用FPGA内部的RAM资源实现ROM,但这不是真正意义上的ROM,而是每次上电都会把初始化的值先写入RAM。Vivado软件中提供了ROM的IP核 , 我们只需通过IP核例化一个ROM,根据ROM的读时序来读取R

    2024年02月07日
    浏览(32)
  • ZYNQ AC7020C的“点LED”实验

    一、创建 Vivado 工程 1、启动 Vivado 2、在 Vivado 开发环境里点击“Create New Project”,创建一个新的工程 3、弹出一个建立新工程的向导,点击“Next” 4、在弹出的对话框中输入工程名和工程存放的目录。需要注意工程路径“Project location”不能有中文、空格,路径名称也不能太长

    2024年02月20日
    浏览(27)
  • zynq板zedboard+vitis设计 (一) hello world实验

    研究生跟着导师做项目,买了两块zedboard板子,我拿到一个,于是从零开始学zynq相关知识以及vivado的使用,经过两三个月的研究,终于开始入门了。开始写下这系列博客,一是整理记录自己所学,二是希望能够和大家进行交流探讨,共同进步。 开发板就是zedboard,vivado用的是

    2024年01月23日
    浏览(23)
  • linuxARM裸机学习笔记(5)----定时器按键消抖和高精度延时实验

    之前的延时消抖,是直接借助delay函数进行的,但是这样会浪费CPU的性能。我们采用延时函数的方式实现,可以实现快进快出。  定时器消抖,必须是在t3的时间点才可以,当在t1,t2的时间点每次进入中断函数都要重新开启定时器的计时 但是,这两个时间点的时间小于定时器设

    2024年02月14日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包