基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器(模块化编写)

基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器(模块化编写)

  • 1. 实验要求
  • 2. 功能分析
  • 3. 模块设计
  • 4. 波形图
    • 4.1 按键消抖模块
    • 4.2 按键控制蜂鸣器模块
  • 5.代码编写
    • 5.1 rtl代码
    • 5.2 测试代码
  • 6. 代码仿真
  • 7. 添加约束文件并分析综合

在上期的内容中,我们通过模拟按键控制led,这一期学习的内容是:按键控制蜂鸣器

1. 实验要求

在这里插入图片描述

通过按键控制领航者底板上的蜂鸣器,要求如下:

  • 初始状态蜂鸣器响起
  • 按下一次按键,改变一次按键的状态
  • 需要对输入的按键信号进行消抖,消抖的时间为20ms
  • 按下复位按键,蜂鸣器恢复默认状态

2. 功能分析

首先我们需要看一下蜂鸣器相关的原理图:
在这里插入图片描述
可以看到蜂鸣器通过一个8050的三极管驱动,连接到FPGA芯片的Bank35 ,引脚为L23。需要让蜂鸣器叫的话,给高电平就可以。

关于按键部分的内容,可以参考本系列的前面几篇,这里不做介绍。

3. 模块设计

在这里插入图片描述
由于本次的实验内容中需要我们设计多个模块,所以我设计了上述的功能框图,可以分为下面三个子模块:

  1. 按键消抖模块:作用是对输入的按键信号进行一个20ms的消抖
  2. 按键控制蜂鸣器模块:作用是对消抖之后的数据边沿采集,通过采集到的信号沿控制蜂鸣器
  3. 按键控制蜂鸣器顶层模块:分别例化了按键消抖模块和按键控制蜂鸣器模块,完成整个实验要求。

4. 波形图

4.1 按键消抖模块

在这里插入图片描述
为了防止按键的输入信号在采集的过程中出现亚稳态,我这里进行了打两拍的操作。同时为了实现按键的消抖,我也定义了一个cnt,用来记录电平保持稳定的时间,当这个时间大于20ms时才任务是按键按下了,这样就实现了按键的消抖

4.2 按键控制蜂鸣器模块

在这里插入图片描述
由于按键控制蜂鸣器模块的按键输入是消抖的后的按键信息(已经打过两拍了),所以我这里只打一个拍,用来计算是否产生了下降沿,从而判断按键是否按下

【注】:由于顶层按键控制蜂鸣器只是例化了上述两个模块,因此这里就不绘制波形图了,之间看后面仿真结果就可以。

5.代码编写

5.1 rtl代码

  1. 按键消抖模块:key_filter.v
//模块的端口定义
module key_filter(input  sys_clk,input  sys_rst_n,input  key,output reg key_filter);reg key_d0;     // 打两拍的变量定义
reg key_d1;reg change;     //这个是用来确定的是否有电平变化的,为1表示有电平变化,为0表示没有//定义计数的变量,用来判断电平是否持续了20ms
reg [19:0] cnt;
//CNT_MAX用来确定按键消抖的时间, CNT_MAX =  20ms /  (1s / 50Mhz ) =  1000_000 ,其中20ms是消抖的时间,50Mhz是系统时钟频率
parameter CNT_MAX = 20'd1000_000;   //对输入的key信号,打两拍操作
always @(posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)   begin   //初始状态下,d0和d1都是高电平,和按键未按下时一致key_d0 <= 1'b1;key_d1 <= 1'b1;endelse begin       //运行状态下,开始打拍key_d0 <= key;key_d1 <= key_d0;end
end//检测是否有电平变化,如果有的话,把change置1,否则保持0
always @(posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)change <= 1'b0;else begin if ( key_d0 != key_d1 )change <= 1'b1;else change <= 1'b0;end
end//如果change为1,说明电平有变化,重新开始计数,否则cnt减一,减到0停止
always @(posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0) cnt <= 20'd0;else beginif(change == 1'b1)cnt <= CNT_MAX;else beginif(cnt >20'd0)cnt <= cnt - 20'd1;elsecnt <= 20'd0;endend
end//如果cnt顺利的减到了1,说明电平保持了20ms,可以输出
always @(posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0) key_filter <= 1'b1;else beginif(cnt == 20'd1)key_filter <= key_d1; elsekey_filter <= key_filter;end
endendmodule

大致流程如下:首先对输入的按键信号大量拍,判断是否按键的电平是否变化,如果变化就把cnt置为最大值,如果没有变化,cnt每个系统时钟减1,直到减到1,表示抖动结束,输出当前的按键信息,否则输出上一次的按键信息。

  1. 按键控制蜂鸣器模块:key_beep.v
    module key_beep(input sys_clk,input sys_rst_n,input key_filter, //消抖后按键值output reg beep //蜂鸣器
);reg key_filter_d0; //将消抖后的按键值延迟一个时钟周期wire neg_key_filter; //按键有效脉信号//捕获按键端口的下降沿,得到一个时钟周期的脉冲信号
assign neg_key_filter = (~key_filter) & key_filter_d0;//对按键端口的数据延迟一个时钟周期
always @ (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)key_filter_d0 <= 1'b1;elsekey_filter_d0 <= key_filter;
end//每次按键按下时,就翻转蜂鸣器的状态
always @ (posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)beep <= 1'b1;else if(neg_key_filter) //有效的一次按键被按下beep <= ~beep;elsebeep <= beep;
end
endmodule

大致流程如下:对消抖之后的按键输入打一个拍,用来判断是否产生下降沿,如果产生下降沿,说明有按键按下,改变一次蜂鸣器的状态。

  1. 顶层按键控制蜂鸣器模块:top_key_beep.v
module top_key_beep(input sys_clk , //系统时钟input sys_rst_n , //系统复位,低电平有效input key , //按键output beep //蜂鸣器
);parameter CNT_MAX = 20'd100_0000; //消抖时间 20mswire key_filter ; //按键消抖后的值//例化按键消抖模块
key_filter #( .CNT_MAX (CNT_MAX) ) u_key_filter(.sys_clk        (sys_clk),.sys_rst_n      (sys_rst_n),.key            (key),.key_filter     (key_filter)
);//例化蜂鸣器控制模块
key_beep u_key_beep (.sys_clk        (sys_clk),.sys_rst_n      (sys_rst_n),.key_filter     (key_filter),.beep           (beep)
);
endmodule

5.2 测试代码

`timescale 1ns/1ns  //仿真单位/精度module tb_top_key_beep();parameter CLK_PERIOD = 20;      //时钟周期20ms
parameter CNT_MAX = 20'd10;     //消抖时间 200ns//定义输入和输出的变量
reg     sys_clk;
reg     sys_rst_n;
reg     key;wire beep;//这里用来产生按键按下的信息
initial beginsys_clk <=1'b0;sys_rst_n <=1'b0;key <= 1'b0;    #190sys_rst_n <=1'b1;key <= 1'b1;    //抖动开始#20key <= 1'b0;#30key <= 1'b1;#40key <= 1'b0;#30key <= 1'b1;#40key <= 1'b0;    //抖动结束#300key <= 1'b1;    //松开按键,抖动开始#40key <= 1'b0;#30key <= 1'b1;    //抖动结束   end//产生时钟
always #(CLK_PERIOD/2) sys_clk = ~sys_clk;//例化测试设计
top_key_beep  #(.CNT_MAX (CNT_MAX) )  u_top_key_beep(.sys_clk    (sys_clk),.sys_rst_n  (sys_rst_n),.key        (key),.beep       (beep)
);endmodule

【注】:这里的测试代码只针对顶层文件,底层的模块测试代码,暂时不需要。

6. 代码仿真

如下是仿真的结果:
在这里插入图片描述
可以看到仿真的结果和我们话的波形图是基本一致的,并且小于200ns的抖动都已经被滤除了,很不错。

7. 添加约束文件并分析综合

首先我们添加对应的约束文件

#时序约束
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
#IO 管脚约束
set_property -dict {PACKAGE_PIN M14 IOSTANDARD LVCMOS33} [get_ports beep]
set_property -dict {PACKAGE_PIN L14 IOSTANDARD LVCMOS33} [get_ports key]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

完成之后,分析综合,得到如下结果:

  1. 顶层模块:
    在这里插入图片描述
    可以看到里面分别由两个子模块连接,下面是子模块的内部结构。

  2. 按键消抖模块

在这里插入图片描述

  1. 按键控制蜂鸣器模块
    在这里插入图片描述
    下一步就是生成比特流文件,然后上板调试了,这里结果我就还是不展示了。

以上就是本期的所有内容,创造不易,点个关注再走呗。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux环境GitLab服务部署安装及使用

一、GitLab介绍 GitLab是利用Ruby onRails一个开源的版本管理系统&#xff0c;实现一个自托管的Git项目仓库&#xff0c;可通过Web界面进行访问公开的或者私人项目。 二、GitLab安装 1、先安装相关依赖 yum -y install policycoreutils openssh-server openssh-clients postf…

视频码率到底是什么?详细说明

视频码率&#xff08;Video Bitrate&#xff09;是指在单位时间内&#xff08;通常是每秒&#xff09;传输或处理的视频数据量&#xff0c;用比特&#xff08;bit&#xff09;表示。它通常用来衡量视频文件的压缩程度和质量&#xff0c;码率越高&#xff0c;视频质量越好&#…

企业多套系统如何一步步实现对接完成闭环?

前言 很多企业用着用着突然发现企业内部有很多的系统&#xff0c;有ERP、CRM、MES、PLM各个系统还比较独立上线时间不一致&#xff0c;主数据包袱很重。这期就讲讲面对情况如何实施对接的案例。 客户背景 公司专注于健康科技领域&#xff0c;致力于打造国际化的专业健康管理…

MySQL大小写敏感、MySQL设置字段大小写敏感

文章目录 一、MySQL大小写敏感规则二、设置数据库及表名大小写敏感 2.1、查询库名及表名是否大小写敏感2.2、修改库名及表名大小写敏感 三、MySQL列名大小写不敏感四、lower_case_table_name与校对规则 4.1、验证校对规则影响大小写敏感4.1、验证校对规则影响排序 五、设置字段…

【HarmonyOS开发】超详细的ArkTS入门

安装DevEco Studio和新建项目就不多说了&#xff0c;可以移步官网 就可以把他们拆成这几个部分了&#xff0c;如果看不懂可以暂时忽略下面冒号后面的内容 装饰器&#xff1a;用于装饰类、结构、方法以及变量&#xff0c;并赋予其特殊的含义。如上述示例中Entry、Component和St…

如何在本地环境中模拟使用https

1.生成私钥文件&#xff0c;其中out输出路径可以自定义 openssl genrsa -out D:\localhost.key 2048 2 生成证书签名请求&#xff08;CSR&#xff09;&#xff0c;根据第一步正确指定私钥路径&#xff0c;和签名请求 openssl req -new -key D:\localhost.key -out D:\localhos…

认识自定义协议

经过前面的介绍&#xff0c;我们知道TCP/IP协议有一组五层模型&#xff0c;从上往下为应用层、传输层、网络层、数据链路层和物理层&#xff0c;且在网络中传输的数据都必须经过这几层模型的封装和分用&#xff0c;作为程序员&#xff0c;我们最经常打交道的就是应用层。程序员…

在Node.js局域网调试https的Vue项目

需求&#xff1a; 最近在测试在网页端&#xff08;HTML5&#xff09;调用移动设备的定位等权限功能&#xff0c;发现某些功能是必须保证域名在https下的否则会出现不正常现象。 解决&#xff1a; 1.在线生成和证书 访问&#xff1a;CSR文件生成工具-中国数字证书CHINASSL …

接口性能优化宝典:解决性能瓶颈的策略与实践

目录 一、直面索引 &#xff08;一&#xff09;索引优化的常见场景 &#xff08;二&#xff09;如何检查索引的使用情况 &#xff08;三&#xff09;如何避免索引失效 &#xff08;四&#xff09;强制选择索引 二、提升 SQL 执行效率 &#xff08;一&#xff09;避免不必…

linux 系列服务器 高并发下ulimit优化文档

系统输入 ulimit -a 结果如下 解除 Linux 系统的最大进程数 要解除或提高 Linux 系统的最大进程数&#xff0c;可以修改 ulimit 设置和 /etc/security/limits.conf 文件中的限制。 临时修改 ulimit 设置 可以使用 ulimit 命令来查看和修改当前会话的最大进程数&#xff1a; 查…

LinuxTCP编程详解

目录 一、创建套接字 二、绑定套接字 示例 三、监听套接字 四、等待套接字 五、服务器端示例 六、连接套接字 七、客户端示例 八、Send和Recv C/S模式&#xff1a;Client客户端、Server服务器 TCP编程基于socket套接字实现&#xff0c;因此也习惯称为Socket编程 一、…

我的后疫情时代DevOps

看了一下上一篇博文写作时间是四月份&#xff0c;一晃眼已经快八个月了&#xff0c;这段时间解决了什么&#xff1f;好像没什么起眼的事情&#xff0c;只有两件事情印象深刻&#xff1a; 1&#xff09;没钱&#xff1b; 2&#xff09;裁员。 如果你所在的单位是私营企业&#x…

增量预训练网络安全大模型的一次尝试

一、背景 探索使用网络安全知识&#xff0c;对开源基模型进行增强&#xff0c;评估是否能使基模型在网络安全领域表现出更好地专业度。 项目基于云起无垠SecGPT开源项目&#xff0c;在hugeface开源数据集的基础上&#xff0c;增加了自有预训练数据&#xff0c;进行增量预训练…

多线程---创建及方法

*线程创建的方式&#xff1a; 1.继承Thread类&#xff0c;重写run方法。 2.实现Runnable接口&#xff0c;重写run方法。 实际这两个run方法都重写的是Runnable中的run方法 简化方法&#xff1a; 1.匿名内部类创建Thread 子类对象 Thread thread new Thread(){Overridepub…

365天深度学习训练营-第P7周:马铃薯病害识别(VGG-16复现)

文为「365天深度学习训练营」内部文章 参考本文所写记录性文章&#xff0c;请在文章开头带上「&#x1f449;声明」 &#x1f37a; 要求&#xff1a; 自己搭建VGG-16网络框架【达成√】调用官方的VGG-16网络框架【达成√】如何查看模型的参数量以及相关指标【达成√】 &#…

【联表查询】.NET开源 ORM 框架 SqlSugar 系列

.NET开源 ORM 框架 SqlSugar 系列 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务…

诗集鉴赏别有韵味——单例模式与工厂模式的浪漫邂逅

原文节选&#xff0c;出自两汉乐府诗集的《陌上桑》 日出东南隅&#xff0c;照我秦氏楼。秦氏有好女&#xff0c;自名为罗敷。罗敷喜蚕桑&#xff0c;采桑城南隅。青丝为笼系&#xff0c;桂枝为笼钩。头上倭堕髻&#xff0c;耳中明月珠。缃绮为下裙&#xff0c;紫绮为上襦。行者…

重学SpringBoot3-RestTemplate配置与使用详解

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-RestTemplate配置与使用详解 1. 简介2. 环境要求3. 基础配置3.1 添加依赖3.2 RestTemplate配置类 4. 高级配置4.1 自定义连接池配置4.2 错误处理配置 5.…

基于YOLO模型的目标检测与识别实现在ESP32-S3 EYE上全流程部署

前言 文章首发于 基于YOLO模型的目标检测与识别实现在ESP32-S3 EYE上全流程部署 文章目录 前言项目环境安装ESP-IDF安装开发环境运行环境 训练数据集准备添加自定义数据集 下载预训练模型训练 YOLO 模型模型量化和格式转换模型结果评估训练损失评估指标模型推理 模型部署部署环…

Vue中使用ECharts图表中的阈值标记(附源码)

在数据处理和可视化领域&#xff0c;我们经常需要对一系列数据点进行分析。本文将介绍如何在给定的数据点中找到对应于特定Y值的X值&#xff0c;并设置标线起始点标记在ECharts图表中&#xff0c;效果图如下&#xff1a; 实现步骤 1、数据准备 let seriesData [// 提供日期…