跟着逻辑先生学习FPGA-第六课 无源蜂鸣器发声实验

硬件平台:征战Pro开发板
软件平台:Vivado2018.3
仿真软件:Modelsim10.6d
文本编译器:Notepad++

征战Pro开发板资料
链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwd=x3u8
提取码:x3u8

1 知识背景

1.1 蜂鸣器简介

蜂鸣器按照结构原理不同可分为压电式蜂鸣器和电磁式蜂鸣器。 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、 阻抗匹配器及共鸣箱、外壳等组成; 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。压电式蜂鸣器是利用压电效应原理工作的,当对其施加交变电压时它会产生机械振动发声; 电磁式蜂鸣器是接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场, 振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
压电式蜂鸣器和电磁式蜂鸣器由于发音原理不同, 产生的声音信号也不一样。 压电式结构简单耐用但音调单一,适用于报警器等设备; 而电磁式由于音质好,所以多用于语音、音乐等设备。 本次实验使用的蜂鸣器为电磁式蜂鸣器。
蜂鸣器按照驱动方式不同又可分为有源蜂鸣器和无源蜂鸣器,其主要区别为蜂鸣器内部是否含有震荡源。一般的有源蜂鸣器内部自带了震荡源,只要通电就会发声。而无源蜂鸣器由于不含内部震荡源,需要外接震荡信号才能发声,因此如果用直流信号无法令其鸣叫,这就需要用 2K~5K 的方波(声音频率)去驱动。
在这里插入图片描述
图6-6- 1有源蜂鸣器(左)和无源蜂鸣器(右)

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

1.2 无源蜂鸣器驱动原理

无源蜂鸣器与有缘蜂鸣器不同,因其内部不带震荡源, 所以其无法向有源蜂鸣器那样直接用直流信号驱动, 这里需要使用 PWM 方波才能驱动其发声。
如何发出不同的声音呢? 上面说到需要使用 PWM 方波才能驱动其发声,所以这里我们只要控制输入的 PWM 方波, 输入不同的 PWM 方波发出的声音就不一样了。而不同频率和占空比的方波发出的声音是不同的,其中频率对音调有影响,占空比对音量大小有影响。所以我们只需产生不同频率和占空比的 PWM 方波去驱动无源蜂鸣器就能让无源蜂鸣器发出不同的音调了。

1.3 PWM简介

PWM 波即脉冲宽度调制,英文全称 Pulse Width Modulation。 PWM 控制技术广泛应用在测量、通信、功率控制与变换的等众多领域中,应用的逆变电路绝大部分是 PWM 型。 以下为周期为 1KHz,500Hz,高电平宽度占比(占空比)分别为 50%、60%、50%的波形图:在这里插入图片描述图6-6- 2频率占空比示意图
由上图可知,当信号周期一定,信号高电平时间所占信号周期的百分比不一样,即为不同占空比的 PWM 波。在逆变电路中,当使用这样的波形去驱动 MOS 管的导通时,由于一个周期内不同占空比的 PWM 信号其高电平持续长度不一样,因此使得 MOS 管的开通时间也不一样,从而使得电路中的平均电流也不一样。 因此,通过调整 PWM 波的占空比即可调整被控制电路中的平均电流。
而除了调整 PWM 信号的占空比, PWM 信号的周期也是可以调整的,例如,在逆变电路中,使用 IGBT 作为开关器件,常见开关频率为几 K 到几十 K,而使用 MOS 管作为开关器件,其开关频率则可高达几百 K。因此,对于不同的器件,对驱动信号的频率要求也不一样,还需要能够对 PWM 波的频率进行调整。
通过以上分析,可以看出,要设计一个 PWM 波形,需要能够实现对信号的频率和占空比的调节。

1.4 音调与频率对应关系

首先对“哆来咪发梭拉西”7 个音调的频率找到对应值,具体见下表(分别为低音、中音和高音),频率的单位是Hz
表6-6- 1 音调与频率对应关系表
在这里插入图片描述

2 实验任务

本章将使用的蜂鸣器电路,并使用 FPGA 来实现驱动无源蜂鸣器按照“哆来咪发梭拉西”7 个音调发声,每个音调保持 0.5s 自动跳到下一个音调。

3 硬件设计

3.1 原理图分析

在这里插入图片描述
图6-6- 3蜂鸣器控制电路原理图

在上述电路中,D9 起保护三极管的作用,当三极管突然截止时,无源蜂鸣器两端产生的瞬时感应电动势可以通过 D9 迅速释放掉,避免叠加到三极管集电极上从而击穿三极管; BEEP 端口接 FPGA 输出管脚,使用时只需要在 BEEP信号上输入 2~5KHz 的 PWM 波,就能驱动蜂鸣器按照既定的频率产生振动信号。

3.2 管脚映射表

表6-6- 2 管脚映射表
在这里插入图片描述

3.3 编写XDC约束文件

在这里插入图片描述

4 程序设计

为了让我们的代码能更好的重复利用,我们尽可能将代码按功能模块来进行划分,比如我们现在这个实验,可以划分成三个部份。

    1. 顶层模块(beep_top),用于例化各个功能模块
    1. 高低电平计数器产生模块(pwm_num_gen),用于每0.5s生成对应频率的高低电平计数,将该计数值输出给pwm模块
    1. PWM方波生成模块(pwm),根据高低电平计数值生成pwm波,驱动无源蜂鸣器。

4.1 顶层模块(beep_top)

4.1.1 模块框图

在这里插入图片描述
图6-6- 4 顶层模块框图
pwm_num_gen 模块生成 PWM 波的高电平计数值和低电平计数值以及计数值有效标志,传给 PWM 波生成模块(pwm)。

4.1.2 设计思路

在本实验中,顶层模块只用于例化各个功能模块,比较简单,此处不做讲解。

4.1.3 代码编写

限于篇幅,仅贴出部份代码(详见 Source 文件夹下 beep_top.v 文件)
定义模块端口,代码如下所示:
在这里插入图片描述

4.2高低电平计数器产生模块(pwm_num_gen)

4.2.1模块框图

在这里插入图片描述
图6-6- 5 高低电平计数器产生模块

  • 输入端口:
    clk:时钟信号,50Mhz,来源于晶振
    rst_n:复位信号,低电平复位,来源于按键
  • 输出端口:
    pwm_h_num:PWM波高电平计数值,传给PWM模块
    pwm_l_num:PWM波低电平计数值,传给PWM模块
    pwm_num_vld:PWM波计数值有效标志,高脉冲有效,传给PWM模块

4.2.2 设计思路

通过前面的学习,我们知道音调是受频率影响的,不同的频率产生的不同的音调,所以这里我们需产生七个不同的频率以发出七个音调,而占空比主要是对音调的音量有影响,这里占空比我们保持为 50% 即可。我们以中音D调为例,七个音调所对应的频率,如下表所示
表6-6- 3 音频与频率关系对应表
在这里插入图片描述
所以该实验我们只要循环产生占空比为 50%的七个音调频率即可。该模块产生对应频率的高低电平计数值。
我们以音调“Do”为例,该音调的频率为 294, 所以这里我们需输出频率为 294hz, 占空比为 50% 的 PWM 方波。
首先是音调的频率我们该如何产生?我们先计算该频率单个方波的时间: 1 / 294 ≈0.003401361s= 3401360ns; 而我们单个系统时钟(50MHz) 的时间为:1 / 50000000 =0.00000002s = 20ns; 所以我们需用:3401360/ 20 ≈ 170068 个系统时钟去产生一个 PWM波,该 PWM 波形的频率即为 294。占空比为 50% 的 PWM 方波,那么高电平和低电平的时间是一样的,即为 170068 / 2 = 85034 个系统时钟。
根据实验任务,每 0.5s 我们更新高低电平的计数值,同时产生一个高低电平计数值的有效标志。第一个 0.5s 我们将频率 294Hz 对应的高低电平计数值赋值给输出端口;第二个 0.5s 我们将频率 330Hz 对应的高低电平计数值赋值给输出端口…第六个 0.5s 我们将频率 556Hz 对应的高低电平计数值赋值给输出端口;依次循环,我们可以画出一个大概的波形图,如下所示:
在这里插入图片描述
图6-6- 6 高低电平计数器模块波形图

4.2.3 代码编写

限于篇幅,仅贴出部份代码(详见 Source 文件夹下 pwm_num_gen.v 文件)
定义模块端口,代码如下所示:
在这里插入图片描述
通过 parameter 语句,定义了 0.5s 所包含的时钟个数,同时还定义了不同频率的 PWM 方波一个周期的时钟个数,代码如下所示:
在这里插入图片描述
定义了一个 switch_cnt 寄存器,用于表示 7 个音调,每 0.5 秒 switch_cnt 进行加 1,加到 6 后再置为 0,在 0~6 之间循环。代码如下所示:在这里插入图片描述
定义一个 pwm_num 表示 PWM 方波一个周期包含的时钟个数,再根据 switch_cnt 的值,给 pwm_num 赋值,注意代码第 68 行,为了保证 case 语句的完整,一定要加上 default ,即使 default 这个语句在目前代码没有任务功能,也需要加上。代码如下所示:在这里插入图片描述
由于这个模块是需要输出高电平和低电平所包含的时钟个数,所以我们还需要用一个除以 2 的运算来得到这两个值。
在 Verilog 中,我们可以有很多办法来实现除以 2 操作。但是笔者认为用移位拼接的方式是最贴近 FPGA 的方式,代码如下:
在这里插入图片描述

4.3 PWM方波生成模块(pwm)

4.3.1 模块框图


图6-6- 7 PWM方波生成模块

4.3.2 设计思路

该模块定义了两个端口,高电包含时钟个数 pwm_h_num 和低电平包含时钟个pwm_l_num,根据这两个端口,我们知道一个PWM周期所包含的时钟个数为pwm_h_num + pwm_l_num。然后通过一个计数器 pwm_cnt,该计数器在0~pwm_h_num + pwm_l_num - 1之间一直循环,pwm方波就是判断 pwm_cnt 的值,当小于pmw_h_num -1 时置为高电平,否则置为低电平,如此就生成了一个我们想要的PWM方波。

4.3.3 代码编写

限于篇幅,仅贴出部份代码(详见 Source 文件夹下 pwm.v 文件)
定义模块端口,代码如下所示:
在这里插入图片描述
定义了一个pwm_cnt计数器,该计数器在0~pwm_h_num + pwm_l_num - 1之间一直循环。为什么要减 1 呢?这是因为我们是从 0 开始计数的。
同时还要在时钟个数有效标志(pwm_num_vld)等于1时,将 pwm_cnt 清零,此处为什么要这样处理呢?大家想一下,因为我们的 pwm_cnt 是一直在计数,同时pwm_h_num,pwm_l_num的值也在随着每个0.5秒在变化。那么有没有一种可能,当switch_cnt等于1时,pwm_cnt的计数值已经超过了它本应计数的最大值(151515),这样pwm_cnt就会一直计数,直到溢出,再重新从0开始,波形如图所示,虽然在我们这个实验,这个问题不会对我们的实际效果产生影响,但是这的确是一个容易出问题的点,笔者仅仅抛砖引玉,希望大家在做项目的时候做一个有心人。
在这里插入图片描述
图6-6- 8 PWM波生成模块波形图
代码如下所示:
在这里插入图片描述
接下来通过判断计数器pwm_cnt的值,给pwm_out信号赋值,生成一个pwm方波,代码如下所示:
在这里插入图片描述

5 仿真验证

5.1 顶层模块(beep_top)模块仿真验证

5.1.1 仿真激励代码编写

由于在前面章节我们已经把仿真脚本写好了,这一章我们只用将 Sim 这个文件夹拷贝到我们当前课程文件夹中,文件结构如下所示:
在这里插入图片描述
图6-6- 9 文件结构

打开Sim文件夹,将“tb_led_shark.v”文件改为“tb_beep_top.v”,然后使用“Notepad++”工具打开“tb_beep_top.v”文件,就可以开始编写仿真代码了。限于篇幅,仅贴出部份代码,详见(Sim文件夹tb_beep_top.v文件)
在这里插入图片描述
为了节约仿真时间,我们在仿真文件中重新定义了 pwm_num_gen 模块中的参数,同比缩小 100 倍,代码如下所示:
在这里插入图片描述

5.1.2 批处理仿真

仿真代码编写好,就可以使用批处理仿真了,在该章节我们可以不用再更改 modelsim.bat文件。sim.do 文件也仅仅只用修改一处地方,如下图所示:
在这里插入图片描述
此处改为我们当前的仿真代码模块名:tb_beep_top,改好以后,保存。
双击 modelsim.bat,我们就不管了,先喝茶,等软件自已跑(具体步骤参考前一章节)

5.1.3 仿真波形分析

我们先看pwm_num_gen模块,不同的switch_cnt值对应不同的pwm_num,pwm_h_cnt 和pwm_l_cnt 等于pwm_num的一半,与设计相符,仿真波形如下所示:
在这里插入图片描述
图6-6- 10 仿真波形1
接着我们观察pwm模块的仿真,小于等于 pwm_h_num -1 (849)时 pwm 输出高电平,大于 849 时输出低电平,与设计相符。仿真波形如下:
在这里插入图片描述
图6-6- 11仿真波形2
再看看 PWM 整体仿真,可以看到 pwm_out 输出的是占空比 50% 的方波,与设计相符,仿真波形如下:
在这里插入图片描述
图6-6- 12 仿真波形3

6 综合编译

在前面我们已经将Source里面的源码(xx.v)和约束文件(pin.xdc)通过notepad++ 软件编辑好了,并且通过Modelsim进行了功能仿真,接下来我们新建Vivado工程并生成bit文件。具体步骤见《6-1 LED灯闪烁实验》,此处不再赘述。

7 下载验证

程序下载进去后,可以听到“哆来咪发梭拉西”7 个音调发声,每个音调保持0.5s自动跳到下一个音调。

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

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

相关文章

TensorFlow Quantum快速编程(高级篇)

五、实战:量子分类器应用 5.1 数据准备 在实战构建量子分类器时,数据准备是基石环节。选用鸢尾花数据集,这一经典数据集在机器学习领域应用广泛,其涵盖了三种鸢尾花品种的样本,每个样本包含花萼长度、花萼宽度、花瓣长度、花瓣宽度四个特征。鉴于本次构建二分类量子分类…

Mysql进阶篇

一:存储引擎 二:索引 2.1 索引概述 索引(index)帮助mysql高效获取数据的数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用&…

通过gradle发布aar或jar携带sources-jar到maven nexus

找了很久,没有找到满意的。终于找到一个好的办法。 gradle7.x适用。比以前的写法简洁。 发布传统的jar工程 比如okhttp,fastjson等项目,纯java工程。 直接创建新文件publish.gradle: apply plugin: maven-publishProperties properties …

ELK日志分析实战宝典之ElasticSearch从入门到服务器部署与应用

目录 ELK工作原理展示图 一、ElasticSearch介绍(数据搜索和分析) 1.1、特点 1.2、数据组织方式 1.3、特点和优势 1.3.1、分布式架构 1.3.2、强大的搜索功能 1.3.3、数据处理与分析 1.3.4、多数据类型支持 1.3.5、易用性与生态系统 1.3.6、高性…

2025年VGC大众汽车科技社招入职测评综合能力英语口语SHL历年真题汇总、考情分析

早在1978年,大众汽车集团就开始了与中国的联系。1984年,集团在华的第一家合资企业—上汽大众汽车有限公司奠基成立;1991年,一汽-大众汽车有限公司成立;2017年,大众汽车(安徽)有限公司…

嵌入式C语言:二维数组

目录 一、二维数组的定义 二、内存布局 2.1. 内存布局特点 2.2. 内存布局示例 2.2.1. 数组元素地址 2.2.2. 内存布局图(简化表示) 2.3. 初始化对内存布局的影响 三、访问二维数组元素 3.1. 常规下标访问方式 3.2. 通过指针访问 3.2.1. 指向数…

H2数据库在单元测试中的应用

H2数据库特征 用比较简洁的话来介绍h2数据库,就是一款轻量级的内存数据库,支持标准的SQL语法和JDBC API,工业领域中,一般会使用h2来进行单元测试。 这里贴一下h2数据库的主要特征 Very fast database engineOpen sourceWritten…

R语言在森林生态研究中的魔法:结构、功能与稳定性分析——发现数据背后的生态故事!

森林生态系统结构、功能与稳定性分析与可视化研究具有多方面的重要意义,具体如下: 一、理论意义 ●深化生态学理论 通过研究森林生态系统的结构、功能与稳定性,可以深化对生态系统基本理论的理解。例如,生物多样性与生态系统稳定性…

【C++经典例题】求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏: 期待您的关注 题目描述: 原题链接: 求123...n_牛客题霸_牛客网 (nowcoder.com) 解题思路: …

day01-HTML-CSS——基础标签样式表格标签表单标签

目录 此篇为简写笔记下端1-3为之前笔记(强迫症、保证文章连续性)完整版笔记代码模仿新浪新闻首页完成审核不通过发不出去HTMLCSS1 HTML1.1 介绍1.1.1 WebStrom中基本配置 1.2 快速入门1.3 基础标签1.3.1 标题标签1.3.2 hr标签1.3.3 字体标签1.3.4 换行标…

基于Springboot+Vue的仓库管理系统

开发一个基于Spring Boot和Vue的仓库管理系统涉及到前端和后端的开发。本文呢,给出一个简单的开发步骤指南,用于指导初入的新手小白如何开始构建这样一个系统,如果**你想直接学习全部内容,可以直接拉到文末哦。** 开始之前呢给小…

快速导入请求到postman

1.确定请求,右键复制为cURL(bash) 2.postman菜单栏Import-Raw text,粘贴复制的内容保存,请求添加成功

预训练语言模型——BERT

1.预训练思想 有了预训练就相当于模型在培养大学生做任务,不然模型初始化再做任务就像培养小学生 当前数据层面的瓶颈是能用于预训练的语料快被用完了 现在有一个重要方向是让机器自己来生成数据并做微调 1.1 预训练(Pre - training)vs. 传…

数字孪生电网有什么作用?实时云渲染技术又如何赋能智慧电网?

电网系统的结构比较复杂,传统运维模式主要是依赖传感器和人工巡检,难以全面监测管理。而数字孪生技术的应用将推动电网智能化、绿色化的高效转型。 智慧电网利用物理模型、现场测量数据和历史数据,结合云计算、物联网、大数据等技术&#xf…

MiniMind - 从0训练语言模型

文章目录 一、关于 MiniMind 📌项目包含 二、📌 Environment三、📌 Quick Start Test四、📌 Quick Start Train0、克隆项目代码1、环境安装2、如果你需要自己训练3、测试模型推理效果 五、📌 Data sources1、分词器&am…

EasyCVR视频汇聚平台如何配置webrtc播放地址?

EasyCVR安防监控视频系统采用先进的网络传输技术,支持高清视频的接入和传输,能够满足大规模、高并发的远程监控需求。平台支持多协议接入,能将接入到视频流转码为多格式进行分发,包括RTMP、RTSP、HTTP-FLV、WebSocket-FLV、HLS、W…

【GlobalMapper精品教程】093:将tif影像色彩映射表(调色板)转为RGB全彩模式

参考阅读:【ArcGIS微课1000例】0137:色彩映射表转为RGB全彩模式 文章目录 一、Globalmapper中显示模式二、ArcGIS中显示模式三、调色板转为RGB全彩模式四、注意事项一、Globalmapper中显示模式 Globalmapper中,将谷歌等多种来源在线影像下载到本地后,可能会遇到以下数据格…

Postman接口测试05|实战项目笔记

目录 一、项目接口概况 二、单接口测试-登录接口:POST 1、正例 2、反例 ①姓名未注册 ②密码错误 ③姓名为空 ④多参 ⑤少参 ⑥无参 三、批量运行测试用例 四、生成测试报告 1、Postman界面生成 2、Newman命令行生成 五、token鉴权(“…

【css】浏览器强制设置元素状态(hover|focus……)

直接上步骤: 打开浏览器控制台 → 找到样式选项 → 找到:hov选项 → 点击:hov选项,会展开【设置元素状态】。 只要选中就会展示出自己写在css里面的该种状态下的样式了。

Springboot——钉钉(站内)实现登录第三方应用

文章目录 前言准备1、创建钉钉应用,并开放网页应用2、配置网页应用各项参数发布版本 前端改造后端逻辑1、获取应用免登录 Access_token2、通过免登录 Access_token 和 Auth_Code 获取对应登录人信息 注意事项 前言 PC端的钉钉中工作台,增加第三方应用&a…