ZYNQ——按键消抖实验

news2024/12/28 17:40:24

文章目录

  • 原理简介
  • 软件仿真
  • 板上验证


原理简介

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


软件仿真

在进行板上验证之前,先在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

仿真输出结果如下图所示。
在这里插入图片描述
可以看到,首先是两级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

引脚分配如下图所示。
在这里插入图片描述
把比特流文件下载到开发板上验证时结果一直不正确,后来才发现我是在仿真代码的基础上修改的,而仿真代码中的复位是高电平有效,而我正好也给复位分配了一个按键引脚,而按键在不按下时就是高电平,因此,开发板上电后就一直在复位状态,除非按下复位按键,所以我把代码中的复位改为了低电平有效,重新生成比特流文件,下载到开发板验证。
按键消抖实验的开发板验证结果如下面动图所示。
请添加图片描述
可以看到,持续按下开发板上的 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

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

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

相关文章

打死也不要进外包,来看看我在腾讯外包的这2年......

我18年毕业于一个普通二本学校&#xff0c;是一个很不出名的小本科。大学期间专业知识也没有去认真的学习&#xff0c;所以毕业的时候就随便找了一份工作&#xff0c;在一个小公司做功能测试。 记得那时候薪资大概是6k左右&#xff0c;因为是在工厂&#xff0c;工作环境很差&a…

Gitlab 访问令牌更新 替换

引言 访问令牌到期后如何丝滑更换&#xff0c;或则如何更改账户的访问令牌实现权限变动呢&#xff1f;在我们使用访问令牌克隆项目之后&#xff0c;Windows凭据就帮我们记录下了密码。当然密码是不可见的&#xff0c;只能进行删除重新设置&#xff0c;通过凭据管理器进行更改。…

python基于预训练大模型权重实现文本向量化开发构建微博评论数据情感极向识别模型

因为最近的一些项目涉及到了大模型相关的技术开发研究&#xff0c;在我前面的博文中也已经有一些实践记录学习资料分享的文章了&#xff0c;今天是在做模型训练的时候突然想到一个有意思的想法&#xff0c;按照我之前做文本分类的方法&#xff0c;基本主流的技术路线都是先对文…

性能提升571%,32K超长上下文,推理速度提升42%,允许商用,国产开源大模型推出了二代 ChatGLM2-6B...

6月份是火热的夏天&#xff0c;各种火热的 AI 产品也在密集的更新&#xff0c;天越热&#xff0c;大家是干得热火朝天&#xff0c;卷出了新高度。 前有现在大火的 ChatGPT&#xff0c;ChatGPT 更新&#xff1a;大杀器&#xff01;函数调用示范&#xff0c;ChatGPT 3.5/4 双双升…

Java Web JDBC(2)23.6.26

3.6 PreparedStatement PreparedStatement作用&#xff1a; 预编译SQL语句并执行&#xff1a;预防SQL注入问题 3.6.1 代码模拟SQL注入问题 Test public void testLogin() throws Exception {//2. 获取连接&#xff1a;如果连接的是本机mysql并且端口是默认的 3306 可以简化书…

浅谈无线温度监测系统在冶炼厂供配电的应用

安科瑞 华楠 摘要&#xff1a;高压供配电系统运行稳定性与电气元器件连接点温度密切相关&#xff0c;通过与传统测温方法对比&#xff0c;实时在线无线温度监测解决 了密封高压开关柜内部各连接点温度无法检测的难题&#xff0c;满足了供电系统安全稳定运行的要求&#xff0c;降…

redis 主从复制 哨兵 安装部署

学习开始前先了解一下 Redis是一个开源的内存数据结构存储系统&#xff0c;它支持多种数据结构&#xff0c;如字符串、哈希表、列表、集合、有序集合等。Redis最大的特点是数据存储在内存中&#xff0c;因此读写速度非常快&#xff0c;同时也支持数据持久化&#xff0c;可以将数…

吐血整理,接口自动化测试-Config配置文件框架封装(实战)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 configparser的介…

阿里巴巴2023最新版Spring Security王者晋级文档

Spring 是一个非常流行和成功的 Java 应用开发框架。Spring Security 是 Spring 家族中的一个安全管理框架&#xff0c;提供了一套 Web 应用安全性的完整解决方案。在用户认证方面&#xff0c;Spring Security 框架支持主流的认证方式&#xff0c;包括 HTTP 基本认证、HTTP 表单…

输出一个数的十六进制表示

可以使用Integer.toHexString、Long.toHexString得到数值的十六进制表示。 下面的代码示例列出了几种情况&#xff1a; public class Test5 {public static void main(String[] args) {byte b1 0b01101111; System.out.println(Integer.toHexString(b1).toUpperCase());byte…

深度学习的实践层面

目录 1、训练、验证、测试集 2、偏差、方差 3、正则化 4、dropoout正则化 5、其他正则化方法 6、归一化输入 7、梯度消失和梯度爆炸 8、梯度的数值逼近 9、梯度检验 1、训练、验证、测试集 &#xff08;1&#xff09;、早期机器学习领域普遍认可的最好的实践方法&…

海兰一体机电脑U盘重装Win10系统教程图解

海兰一体机电脑是全家人都适用的电脑&#xff0c;使用海兰一体机电脑的用户要怎么用U盘来重装Win10系统&#xff0c;首先用户需要确保电脑能够正常联网&#xff0c;然后再准备一个8G以上的U盘&#xff0c;最后根据小编分享的海兰一体机电脑U盘重装Win10系统教程图解操作即可。 …

PR脚本:音乐鼓点自动节拍打点标记动画BeatEdit

BeatEdit可检测音乐中的节拍并在Premiere Pro时间轴中为其生成标记。可以创建与音乐同步的自动编辑&#xff0c;或者让BeatEdit v2.0.006 激活版协助您进行手动编辑过程。BeatEdit mac版使用节拍信息来生成与音乐同步的全自动编辑。如果需要更多控制&#xff0c;拍子标记也可以…

视唱音准不好的人能练好吗,视唱音准不好怎么办

软件版本&#xff1a;Earmaster7.3.6 无论是普通人还是声乐艺术生&#xff0c;音准是唱好歌的必要条件之一&#xff0c;如果音准不好&#xff0c;唱歌自然会跑调。然而并不是所有人天生都有十分出色的音准&#xff0c;如果不进行后天的训练&#xff0c;是很难找到正确的音准的…

web应用封装成app|超级签名

PP封装是形成APP的最省钱的一种方式。你只需要拥有一个网址就可以通过一些技术处理封装成一个跨iOS和Android的APP&#xff0c;这个过程往往只需要几分钟。在移动互联网时代&#xff0c;拥有一个移动端APP是必不可少的。那么APP是怎样封装的呢&#xff1f; 首先让我们先来了解…

基于深度学习的人脸面部表情识别系统【含Python源码+PyqtUI界面+原理详解】

功能演示 摘要&#xff1a;面部表情识别&#xff08;Facial Expression Recognition&#xff09;是一种通过技术手段识别人物图像中人脸面部表情的技术。本文详细介绍了其实现的技术原理&#xff0c;同时给出完整的Python实现代码、训练好的深度学习模型&#xff0c;并且通过Py…

Python中的四种条件语句结构和应用举例

Python中的四种条件语句结构和应用举例 条件语句是计算机实现分类高效执行计算的重要方法。在许多计算机语言编写&#xff08;C语言&#xff0c;Java语言&#xff0c;matlab语言等&#xff09;的时候&#xff0c;都有涉及条件语句的部分&#xff0c;本文对Python语言中的条件语…

Docker操作镜像与容器常用命令

Docker操作镜像与容器的常用命令 文章目录 Docker操作镜像与容器的常用命令前言1、镜像相关命令1.1 查看镜像1.2 搜索镜像1.3 拉取镜像1.4 删除镜像 2 容器相关命令2.1 查看容器2.2 创建与启动容器2.3 停止与启动容器2.4 文件拷贝2.5 目录挂载2.6 查看容器IP地址2.7 删除容器 总…

金山云联合MiniMax推出MaaS互信推理专区方案 解决大模型与数据互信难题

作为人工智能领域颇具里程碑式的进展&#xff0c;ChatGPT以其惊艳的表现&#xff0c;迅速掀起了行业热潮&#xff0c;使得大模型成为当下最为炙手可热的技术方向之一。但在大模型落地过程中&#xff0c;如何既能保障大模型使用方的数据安全&#xff0c;又能保护大模型提供方的部…

C编译过程 以及 ELF文件(学习笔记)

C编译过程 一个用C语言编写的高级语言程序是从编写到打包、再到编译执行的基本过程&#xff0c;我们知道在CPU上执行的是低级别的机器语言&#xff0c;从高级语言到低级别的机器语言肯定是要经过翻译过程&#xff0c;这个过程大体的过程如下图所示: 在Unix系统中&#xff0c;从…