按键控制蜂鸣器实验

news2024/10/5 22:24:05

目录

按键控制蜂鸣器实验

1、简介

2、实验任务

3、程序设计

3.1、顶层模块代码

3.2、按键消抖模块代码

3.3、蜂鸣器控制模块代码

4、仿真验证

5、板上下载验证

5.1、硬件设计

5.2、添加约束文件.xdc

5.3、板上下载验证


按键控制蜂鸣器实验

       蜂鸣器(Buzzer)是现代常用的一种电子发声器,主要用于产生声音信号。蜂鸣器在生活中已经得到广泛使用,其典型应用包括医疗,消防等领域的各种报警装置以及日常生活中的各种警报器等。本章我们主要学习如何使用按键来控制蜂鸣器发声。

1、简介

       蜂鸣器按照驱动方式主要分为有源蜂鸣器和无源蜂鸣器,其主要区别为蜂鸣器内部是否含有震荡源。一 般的有源蜂鸣器内部自带了震荡源,只要通电就会发声。而无源蜂鸣器由于不含内部震荡源,需要外接震荡信号才能发声。

       如图 10.1.1 所示,从外观上看,两种蜂鸣器很相似,如将两种蜂鸣器的引脚都朝上放置,可以看出有绿色电路板的是无源蜂鸣器,没有电路板而用黑胶封闭的是有源蜂鸣器。

       相较于有源蜂鸣器,无源蜂鸣器成本更低,且发声频率可控。而有源蜂鸣器控制相对简单,由于内部自带震荡源,只要加上合适的直流电压即可发声。本次实验使用的蜂鸣器为图 10.1.2 中的有源蜂鸣器。

2、实验任务

       本节实验任务是使用按键控制蜂鸣器发声。初始状态为蜂鸣器鸣叫,按下 key0 按键后蜂鸣器停止鸣叫,再次按下 key0 按键,蜂鸣器重新鸣叫。

3、程序设计

       由实验任务可知,我们只需要在按键按下时改变蜂鸣器的鸣叫状态,但实际上在按键按下的过程中存在按键抖动的干扰,体现在数字电路中就是不断变化的高低电平,为避免在抖动过程中采集到错误的按键状态,我们需要对按键数据进行消除抖动处理。因此本系统应至少包含按键消抖模块和蜂鸣器控制模块,按键控制蜂鸣器系统框图如图 10.4.1 所示。

       这里我们补充下如何查看软件生成的模块端口及信号连接图。首先在对工程进行编译,然后点击菜单栏的 Open Elaborated DesignYes ,之后弹出的对话框选择 OK,如图 10.4.2 所示:

稍后就可以看到软件生成的模块端口及信号连接图了,如下图 10.4.3 所示:

       打开之后,按下键盘的【Ctrl】键,滚动鼠标的滚轮可以对生连接图进行放大和缩小。模块端口及信号连接图可以比较清晰的查看各个模块端口信号的连接,同时双击模块,也可以进一步查看模块的原理图。

       由图 10.4.3 的连接图可知,顶层模块例化了以下两个模块,按键消抖模块(key_debounce)和蜂鸣器控制模块(beep_control)。顶层模块(top_key_beep)完成了对另外两个模块的例化。按键消抖模块,主要起到延时采样,防止按键抖动的干扰。蜂鸣器控制模块,通过对按键信号的识别,起到控制蜂鸣器鸣叫的作用。

  • 按键消抖模块(key_debounce):对按键信号延时采样,将消抖后的按键信号和按键数据有效信号输出至 beep_control 模块。
  • 蜂鸣器控制模块(beep_control):根据输入的按键信号和按键数据有效信号,来控制蜂鸣器的鸣叫。

       在这里我们介绍按键消抖的原理。通常我们所使用的开关为机械弹性开关,当我们按下或松开按键时,由于弹片的物理特性,不能立即闭合或断开,往往会在断开或闭合的短时间内产生机械抖动,消除这种抖动的过程即称为按键消抖。

       按键消抖可分为硬件消抖和软件消抖。硬件消抖主要使用 RS 触发器或电容等方法实现消抖,一般在按键较少时使用。软件消抖的原理主要为按键按下或松开后延时 5ms—20ms 采样,也可以在检测到按键状态稳定后采样,即避开抖动区域后再采样,如图 10.4.4 所示。

3.1、顶层模块代码

顶层模块代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/05/11 14:03:56
// Design Name: 
// Module Name: top_key_beep
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
//实验任务
//本节实验任务是使用按键控制蜂鸣器发声。初始状态为蜂鸣器鸣叫,
//按下 key0 按键后蜂鸣器停止鸣叫,再次按下 key0 按键,蜂鸣器重新鸣叫。

//顶层模块代码
module top_key_beep(
    input       sys_clk,        //时钟信号50MHz <---达芬奇Pro FPGA
    input       sys_rst_n,       //reset ,low active //系统复位,低电平有效
    
    input       key,              //按键信号 
    output      beep              //蜂鸣器控制信号
    );
    
//wire define
wire        key_value;
wire        key_flag;

//**************************************************************
//**           main code
//**************************************************************

//在顶层模块中实例化了:按键消抖模块、按键控制蜂鸣器模块
//实例化按键消抖模块
key_debounce u_key_debounce(
      .sys_clk            (sys_clk    ),
      .sys_rst_n          (sys_rst_n  ),
      
      .key                (key       ),
      .key_flag           (key_flag  ),
      .key_value          (key_value )
);    
    
//实例化蜂鸣器控制模块
beep_control u_beep_control(
      .sys_clk            (sys_clk   ),
      .sys_rst_n          (sys_rst_n ),
      
      .key_flag           (key_flag  ),
      .key_value          (key_value ),
      .beep               (beep      )
);    

endmodule

在顶层模块中例化了按键消抖模块和按键控制蜂鸣器模块。

3.2、按键消抖模块代码

按键消抖模块代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/05/11 17:03:40
// Design Name: 
// Module Name: key_debounce
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


//按键消抖模块
module key_debounce(
     input          sys_clk,        //50MHz时钟
     input          sys_rst_n,     //复位信号,低频有效
     
     input           key,           //外部按键输入
     output  reg    key_flag,      //按键数据有效信号
     output  reg    key_value      //按键消抖后的数据
);

//reg define
reg  [31:0]   delay_cnt;
reg           key_reg;

//(系统时钟50MHz,一个时钟周期是1/50MHz=0.02us=20ns)(0.2s需计数:0.2s/20ns=10_000_000次)
//(系统时钟200MHz,一个时钟周期是1/200MHz=0.005us=5ns)(20ms需计数:20ms/5ns=4_000_000次)
//*************************************************************
//**        main code
//*************************************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n) begin
        key_reg    <= 1'b1;
        delay_cnt  <= 32'd0;
    end
    else begin
        key_reg <= key;
        if (key_reg != key) begin //一旦检测到按键状态发生变化(有按键按下或者释放)
            //delay_cnt <= 32'd1000_000;//给延时计数器重新装载初始值(计数时间为20ms)
            delay_cnt <= 32'd4; //仅用于仿真
        end
        else begin //按键状态稳定时,计数器递减,开始20ms倒计时
            if (delay_cnt >32'd0)
                 delay_cnt <= delay_cnt - 1'b1;
            else 
                 delay_cnt <= 32'd0;
        end
    end
end

always @(posedge sys_clk or negedge sys_rst_n) begin
    if (!sys_rst_n) begin
        key_flag <= 1'b0;
        key_value <= 1'b1;
    end
    else if (delay_cnt == 32'd1) begin //当计数器递减到1时,说明按键稳定状态维持了20ms
            key_flag <= 1'b1; //此时消抖过程结束,给出一个时钟周期的标志信号
            key_value <= key; //并寄存此时按键的值
        end
    else begin
            key_flag <= 1'b0;
            key_value <= key_value;
    end
end

endmodule

       程序中第 50 行不断检测按键状态,一旦发现按键状态发生改变,就给计数器 delay_cnt 赋初值 1000000。 在按键状态不发生改变时,delay_cnt 递减从而实现倒计时的功能,在倒计时过程中,一旦检测到按键状态发生改变,则说明有抖动产生,此时重新给 delay_cnt 赋初值,并开始新一轮倒计时。在 50Mhz 时钟驱动下,delay_cnt 若能由 1000000 递减至 1,则说明按键状态保持稳定时间达 20ms,此时输出一个时钟周期的通知信号 key_flag,并将此时的按键数据寄存输出。代码第 51 delay_cnt 赋值为 200,这仿真时的延迟数据。

3.3、蜂鸣器控制模块代码

蜂鸣器控制模块的代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/05/11 17:02:56
// Design Name: 
// Module Name: beep_control
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


//蜂鸣器控制模块
module beep_control(
      //input
      input        sys_clk,       //系统时钟
      input        sys_rst_n,      //复位信号,低电平有效
      
      input        key_flag,       //按键有效信号
      input        key_value,      //消抖后的按键信号
      output  reg  beep           //蜂鸣器控制信号
);

//*************************************************
//**        main  code
//*************************************************
always @(posedge sys_clk or negedge sys_rst_n) begin
     if( !sys_rst_n )
          beep <= 1'b1;
     else if( key_flag && (~key_value) ) //判断按键是否按下有效
          beep <= ~beep;
end

endmodule

       beep 初始状态为高电平,蜂鸣器鸣叫,当检测到按键有效信号 key_flay 为高电平,同时按键信号key_value 为低电平时说明按键被有效按下,此时 beep 取反,蜂鸣器停止鸣叫。当按键再次按下时,beep 再次取反,蜂鸣器重新开始鸣叫。

4、仿真验证

为了验证我们的程序,我们在 Vivado 内对代码进行仿真。

Test bench 模块代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/05/11 15:52:20
// Design Name: 
// Module Name: tb_top_key_beep
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//

//Test bench模块
module tb_top_key_beep();

//parameter define 
parameter T = 20;  //达芬奇Pro 系统时钟50MHz
//parameter T = 5;  //200MHz系统时钟 <---黑金 ARTIX7-xc7a35t 没有蜂鸣器

//reg define 
reg        key;
reg        sys_clk;
reg        sys_rst_n;
reg        key_value;

//wire define
wire    beep;

//***********************************************************
//**       main  code
//***********************************************************

//给信号初始值
initial begin
     key                          <= 1'b1;
     sys_clk                      <= 1'b0;
     sys_rst_n                    <= 1'b0;
     #20           sys_rst_n      <= 1'b1; //在第20ns的时候复位信号拉高
     #30           key            <= 1'b0; //在第50ns的时候按下按键
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #170          key            <= 1'b1; //在第300ns的时候松开按键
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #170          key            <= 1'b0; //在第550ns的时候再次按下按键
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #170          key            <= 1'b1; //在第800ns的时候松开按键
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0; //模拟抖动
     #20           key            <= 1'b1; //模拟抖动
     #20           key            <= 1'b0;   
end

//50MHz的时钟,周期则为1/50MHz=20ns,所以每10ns,电平取反一次
always #(T/2) sys_clk <= ~sys_clk;
//always #(T/2) sys_clk_p <= ~sys_clk_p;
//assign sys_clk_n=~sys_clk_p;

//实例化key_beep模块
top_key_beep u_top_key_beep(
     .sys_clk          (sys_clk),
     .sys_rst_n        (sys_rst_n),
     .key              (key),
     .beep             (beep)
);

endmodule

仿真波形图如下:

        测试代码中,为了方便仿真波形的查看,将按键消抖模块中的延时采样的延时时间改为 4 个时钟周期(将按键消抖模块中的第 47 行代码 delay_cnt <= 32'd1000000; 改为 delay_cnt <= 32'd4;)。tb_key_beep 模块中第 44 行到第 68 行为信号的激励。从图 10.4.5 可以看到,第 50ns 时,将 key 拉低,并在 50 130ns 时模拟按键抖动,可见在按键抖动停止后的第 4 个时钟周期时,key_flag 出现一个时钟周期的高电平,同时 beep 被拉低(蜂鸣器停止鸣叫);在第 300ns 时松开按键,随后模拟按键抖动,同理可知在抖动结束后的第四个时钟周期,key_flag 信号被拉高。读者可以仔细观察仿真波形结合代码深入理解,仔细体会 key_flag 信号和 key 信号之间的关系。

5、板上下载验证

5.1、硬件设计

本实验的管脚分配如下表所示:

5.2、添加约束文件.xdc

对应的 key_beep.xdc  约束语句具体如下:
############### clock define 时钟引脚、电平信号约束#######################
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS15} [get_ports sys_clk]
############### reset key define##########################
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS15} [get_ports sys_rst_n]
############### key define ############################
set_property -dict {PACKAGE_PIN T4 IOSTANDARD LVCMOS15} [get_ports key]

set_property -dict {PACKAGE_PIN V7 IOSTANDARD LVCMOS15} [get_ports beep]

5.3、板上下载验证

        编译工程并生成比特流.bit 文件后,接下来我们下载比特流.bit 文件,验证按键控制蜂鸣器的功能。程序下载完成后,蜂鸣器会发出名叫,按下 KEY0 蜂鸣器停止鸣叫,再按下 KEY0 蜂鸣器再次鸣叫。如下图所示:

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

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

相关文章

微机保护主程序框图原理

微机保护主程序框图如图2&#xff0d;5所示。 一、初始化 “初始化”是指保护装置在上电或按下复位键时首先执行的程序&#xff0c;它主要是对单片微机&#xff08;CPU&#xff09;及可编程扩展芯片的工作方式、参数的设置&#xff0c;以便在后面的程序中按预定方案工作。例如…

荨麻疹【指南共识】

慢性自发性荨麻疹达标治疗专家共识&#xff08;2023&#xff09; 参考文献&#xff1a;中华医学会皮肤性病学分会&#xff0c; 中国医师协会皮肤科医师分会. 慢性自发性荨麻疹达标治疗专家共识&#xff08;2023&#xff09;[J]&#xff0e; 中华皮肤科杂志&#xff0c;2023, e2…

在React+ts中集成高德地图(保姆级教程)

前往高德地图开发平台高德开放平台 | 高德地图API 一&#xff1a;申请高德key 去高德官网去创建一个属于自己的地图应用 &#xff08;得到key和秘钥&#xff09; 。 首先&#xff0c;我们要注册一个开发者账号&#xff0c;根据实际情况填写&#xff0c;身份写个人&#xff1a;…

LwIP系列(3):以太网帧、IP、TCP、UDP、IGMP、ICMP帧格式详解

前言 TCP/IP 本质上是软件协议&#xff0c;而LwIP也是对软件协议进行解析处理&#xff0c;所以我们有必要了解下以太网帧、IP、TCP、UDP、IGMP、ICMP帧格式&#xff0c;这样在代码中&#xff0c;才能有的放矢。 以太网帧框架 以太网帧是最底层的原始数据&#xff0c;帧框架如…

Linux用户密码管理

密码复杂度设置 之前写过一篇文章&#xff0c;通过编辑/etc/pam.d下的配置文件来信hi先密码复杂度设置。 这里介绍另一种方法&#xff0c;使用authconfig名来配置。 如果没有安装该软件&#xff0c;输入如下命令安装: yum install authconfig -y 设置方法如下: authconfi…

力扣动态规划专题(六)编辑距离与回文问题 步骤及C++实现

文章目录 392. 判断子序列动态规划双指针 115.不同的子序列583. 两个字符串的删除操作方法一方法二 72. 编辑距离647. 回文子串动态规划双指针 516.最长回文子序列 392. 判断子序列 动态规划 步骤 确定dp数组以及下标的含义 dp[i][j] 表示以下标i-1为结尾的字符串s&#xff0c…

Json数据 通用提取工具 Web版

问题来源 楼主使用Golang 实现了一款通用型 JSON 数据提取工具&#xff0c;支持自动识别 JSON 数据节点并有序提取为 CSV 文件。 看到大家有这样的评论&#xff0c;顺手实现下&#xff0c;~~ 尴尬的是搞完了 &#xff0c;发现 这个论坛注册不足15天&#xff0c;不能回复评论。晕…

迅为RK3568开发板系统编程手册全新升级

iTOP-3568开发板C应用编程手册全新升级&#xff0c;《iTOP-RK3568开发板系统编程手册》旨在帮助刚入门的用户进行入门规划和学习&#xff0c;为系统编程基础指导手册。 第1部分 系统编程初探 第1章 系统编程初探 1.1 什么是系统编程 1.2 系统编程的作用 1.3 系统调用和C语言库函…

R语言使用xlsx包、安装包的经验以及切换工作目录的方法

R语言使用xlsx包 首先不同于读取txt和csv文件&#xff0c;R语言读取xlsx文件需要安装xlsx包 使用下面命令进行安装xlsx install.packages(“xlsx”) 安装过程非常顺利&#xff0c;需要附带安装其它几个包。如果安装出现错误&#xff0c;可以尝试切换网络&#xff0c;使用手机热…

2-css-1

一 CSS 初体验 CSS 定义&#xff1a;层叠样式表 (Cascading Style Sheets&#xff0c;缩写为 CSS&#xff09;&#xff0c;是一种样式表语言&#xff0c;用来描述HTML文档的呈现&#xff08;美化内容&#xff09; CSS 书写在什么位置&#xff1f; title 标签下方哪个标签里面…

2-css-5

一 定位 1 认识 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 定位模式&#xff1a;position边偏移&#xff1a;设置盒子的位置 left right top bottom 2 相对定位 position: relative 特点&#xff1a; 不脱标&#xff0c;占用自己原来位置显示模式…

如何将JSON对象转化为java对象,如何将java对象转化为JSON对象

如何将JSON对象转化为java对象&#xff0c;如何将java对象转化为JSON对象 一、在java中如何构建一个JSON对象 在java中我们可以通过创建JsonObject对象的方式来为其添加相应的参数属性&#xff0c;进而构造JSON对象 1、导入JsonObject的依赖 JsonObject是Gson库中的一个类&…

数据结构--数据结构的基本概念

数据结构–数据结构的基本概念 知识总览&#xff1a; 数据结构的三要素 #mermaid-svg-jflLhauniFK26Yxb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jflLhauniFK26Yxb .error-icon{fill:#552222;}#mermaid-svg-…

软件测试已经人员饱和了?是否选择退出这个行业?

铺天盖地的职场内卷文章充斥我们眼球&#xff0c;给大家带来山大压力&#xff0c;内心焦虑。据闻&#xff0c;2023年有1070万高校应届毕业生涌入用人市场&#xff0c;其中有多少人将卷入软件测试行业呢&#xff1f;而最近大厂毕业之风盛行&#xff0c;对外输出人才&#xff0c;…

从小白到大神之路之学习运维第46天---第三阶段----Ceph分布式存储系统(CentOS7.9版本下安装部署ceph)

第三阶段基础 时 间&#xff1a;2023年6月25日 参加人&#xff1a;全班人员 内 容&#xff1a; Ceph分布式存储系统 目录 一、Ceph概述 二、Ceph 的工作原理和工作流程 三、Ceph 组件包括 1. RADOS 2. OSD 3. MON 4. MDS 5. RGW 6. RBD 7. CephFS 四、安装部…

文心一言 VS 讯飞星火 VS chatgpt (47)-- 算法导论6.1 5题

五、一个已排好序的数组是一个最小堆吗? 文心一言&#xff1a; 一个已排好序的数组不一定是一个最小堆。最小堆是一种特殊的二叉树&#xff0c;它满足以下性质&#xff1a;对于任意节点 x&#xff0c;其父节点 y 的值都小于等于 x 的值。而一个已排好序的数组只是一个有序数…

【FFmpeg实战】压缩数据AVPacket解析

因为FFmpeg更新的比较快&#xff0c;API也会跟着有所变动&#xff0c;所以声明一下&#xff0c;本文使用的FFmpeg版本为V3.3.5。 1.AVPacket简介 AVPacket是FFmpeg中很重要的一个数据结构&#xff0c;它保存了解复用&#xff08;demuxer)之后&#xff0c;解码&#xff08;dec…

TS格式视频的使用

什么是TS文件格式 TS&#xff08;Transport Stream&#xff0c;传输流&#xff09;是一种封装的格式&#xff0c;它的全称为MPEG2-TS。MPEG2-TS是一种标准数据容器格式&#xff0c;传输与存储音视频、节目与系统信息协议数据&#xff0c;主要应用于数字广播系统&#xff0c;例…

在加密数据时,如何选择合适的算法?

我们将分解两种主要类型的加密 - 对称和非对称 - 然后深入研究 5 种最常用的加密算法列表&#xff0c;以前所未有的方式简化它们 加密经常被指责为政治实体隐藏恐怖活动&#xff0c;是始终成为头条新闻的网络安全话题之一。任何对不同类型的加密有充分了解的人都可能会觉得对这…

内网穿透工具cpolar——将内网站点发布至公网、远程连接公司内网电脑

在现代互联的时代&#xff0c;我们经常需要将局域网中的服务器或提供给外部网络进行访问。然而&#xff0c;由于内网通常使用私有IP地址&#xff0c;在没有合适的配置和设置的情况下&#xff0c;对外部网络是不可见的。这就引出了内网穿透技术&#xff0c;它允许我们在不暴露真…