FPGA开发——蜂鸣器实现音乐播放器的设计
一、概述
我们在进行蜂鸣器的学习的时候,总会在想既然蜂鸣器能够发出声音,那么它能够播放音乐吗,今天这篇我们文章我们就一起来学习怎样使用使用蜂鸣器来播放音乐,也就是怎样成为一个音乐播放器。
1、蜂鸣器的类型
在设计的时候其实蜂鸣器的类型也对我们最后所实现的效果有一点影响,蜂鸣器分为有源和无源两种,有源蜂鸣器的器件内部本身就带有振荡器,本身来讲完全不用我们进行外部振荡,二无源蜂鸣器是不带振荡器的,所以当涉及到相关频率使用时就需要我们使用外部振荡。这里因为我们使用PWM进行设计实现,所以如果有条件的话使用无源蜂鸣器所实现的效果会更好。
2、PWM介绍
PWM(Pulse Width Modulation),即脉冲宽度调制,是一种模拟信号电平数字编码方法。它通过将有效的电信号分散成离散形式,从而来降低电信号所传递的平均功率。PWM技术的核心在于通过调节脉冲的时间宽度(占空比)来等效地获得所需要合成的相应幅值和频率的波形。通过调整PWM信号的占空比和频率,可以实现声音的音量调节和音调变化。
- 占空比:占空比是脉冲处于较高电压的时间占整个脉冲周期的百分比。通过改变占空比,可以实现对信号、能量等的调节。例如,在LED电路中,高占空比意味着LED非常明亮,而低占空比则意味着LED较为暗淡。
- 频率:频率是单位时间内脉冲信号的次数。PWM信号的频率越高,控制效果越接近模拟信号,但也会受到电路响应时长的限制。
3、PWM调制的实现方式
硬件实现:许多微控制器和数字信号处理器(DSP)已包括了PWM控制器芯片,因此可以更轻松地实施数字化控制。这些芯片通过内部定时器或计数器来生成PWM信号,并通过调整相关参数来改变占空比和频率。
软件实现:在没有内置PWM控制器的系统中,也可以通过软件编程来模拟PWM信号。这通常涉及到对定时器中断的精确控制,以及在高电平和低电平之间快速切换IO口的输出状态。
4、音符的相关设计
这是关于高中低音符的频率和周期表,我们将会参考这个对代码进行设计。

二、工程实现
1、本次播放的音乐
本次我们设计得比较简单,设计了一个《我有一头小毛驴》的简单音乐播放器,具体乐谱如下:

2、基本构建思路
在本次的设计中,采用了一个音符播放播放0.5秒的设计,针对上述乐谱,采用四个字符为一组的方式进行划分,便于代码的赋值。利用三个计数器完成对于音乐播放的相关设计,第一个播放器用于技术每个音符技术的相关频率,第二个计数器用于对于在0.5秒播放时间内对于每个音符重复的次数进行计数,而第三个计数器用于对音符的播放顺序进行一个计数,由此关于音符的设置就设计完成,最后就是对于蜂鸣器进行占空比调制,对每个音符的频率进行一个8分频就完成了最终功能。
3、设计文件的编写
这里新建一个beep.v文件,如下:
//蜂鸣器
module beep(input clk,input rst_n,output reg beep_out
);
parameter CLK_CLY=50_000_000;//时钟频率
localparam H1 =CLK_CLY/523,H1_L=CLK_CLY/262,H1_H=CLK_CLY/1047,H2 =CLK_CLY/587,H3 =CLK_CLY/659,H4 =CLK_CLY/698,H5 =CLK_CLY/784,H6 =CLK_CLY/880,H7 =CLK_CLY/988;parameter TIME_500MS=25_000_000;//0.5秒reg [17:0] cnt0;// 每个音符频率计数器
wire add_cnt0;
wire end_cnt0;reg [9:0] cnt1;// 0.5秒内音符周期重复个数
wire add_cnt1;
wire end_cnt1;reg [5:0] cnt2;// 计数音符播放顺序
wire add_cnt2;
wire end_cnt2;
reg [15:0] cnt_max;reg [17:0] display;//音符计数器的最大值
//cnt0计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)cnt0<=0;else if(add_cnt0)begin if(end_cnt0)cnt0<=0;elsecnt0<=cnt0+1'b1;end
end
assign add_cnt0=1'b1;
assign end_cnt0=add_cnt0 &&(cnt0==display-1);//cnt1计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)cnt1<=0;else if(add_cnt1)begin if(end_cnt1)cnt1<=0;elsecnt1<=cnt1+1'b1;end
end
assign add_cnt1=end_cnt0;
assign end_cnt1=add_cnt1 &&(cnt1==(TIME_500MS/display-1));//cnt2计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)cnt2<=0;else if(add_cnt2)begin if(end_cnt2)cnt2<=0;elsecnt2<=cnt2+1'b1;end
end
assign add_cnt2=end_cnt1;
assign end_cnt2=add_cnt2 &&(cnt2==50-1);always @(posedge clk or negedge rst_n)beginif(!rst_n)display <=H1;else begincase (cnt2)0:display <=H1_L;1:display <=H1;2:display <=H1;3:display <=H3;4:display <=H5;5:display <=H5;6:display <=H5;7:display <=H5;8:display <=H6;9:display <=H6;10:display <=H6;11:display <=H1_H;12:display <=H5;13:display <=H5;14:display <=H5;15:display <=H5;16:display <=H4;17:display <=H4;18:display <=H4;19:display <=H6;20:display <=H3;21:display <=H3;22:display <=H3;23:display <=H3;24:display <=H2;25:display <=H2;26:display <=H2;27:display <=H2;28:display <=H5;29:display <=H5;30:display <=H5;31:display <=H5;32:display <=H1;33:display <=H1_L;34:display <=H1;35:display <=H3;36:display <=H5;37:display <=H5;38:display <=H5;39:display <=H5;40:display <=H6;41:display <=H6;42:display <=H6;43:display <=H1_H;44:display <=H5;45:display <=H5;46:display <=H5;47:display <=H5;40:display <=H4;41:display <=H4;42:display <=H4;43:display <=H6;44:display <=H3;45:display <=H3;46:display <=H3;47:display <=H3;40:display <=H3;41:display <=H3;42:display <=H2;43:display <=H2;44:display <=H2;45:display <=H3;46:display <=H1;47:display <=H1;48:display <=H1;49:display <=H1;default: display <=H1;endcaseend
end//pwm输出
//蜂鸣器pwm
always @(posedge clk or negedge rst_n) beginif(!rst_n)beginbeep_out <= 1'b1;endelse if(cnt0 == (display>>3))begin//设置占空比beep_out <= 1'b1;endelse if(cnt0==0)beginbeep_out<= 1'b0;end
end
endmodule
4、测试文件的编写
新建beep_tb.v文件,这里出来蜂鸣器输出没有任何激励,所以我们只需要进行时钟和复位进行赋值就行。如下:
//定义时间尺度
`timescale 1ns/1ns
module beep_tb ;//输入信号定义
reg clk ;
reg rst_n ;
wire beep_out ;
//模块例化
beep beep_inst(/*input */ .clk (clk ) ,/*input */ .rst_n (rst_n ) ,/*output */ .beep_out (beep_out )
);//激励信号产生
parameter CLK_CYC = 20;
//时钟
initial clk=1;
always #(CLK_CYC/2)clk=~clk;//复位
initial beginrst_n= 1'b0;#(CLK_CYC*2);#3;//复位结束避开时钟上升沿rst_n= 1'b1;
end
endmodule
5、仿真波形图

通过对于波形图的观察,我们可以看到在三个计数器的不断计数之下蜂鸣器的输出波形占空比在不断进行变化 ,并且在经过对于计数器进行检查后没有发现什么问题。(这里方针波形图太长,没有截全),感兴趣的可以去自行进行仿真观察。最后进行下板验证之后,蜂鸣器也进行了正常播放,我们的设计成功。
相关文章:
FPGA开发——蜂鸣器实现音乐播放器的设计
一、概述 我们在进行蜂鸣器的学习的时候,总会在想既然蜂鸣器能够发出声音,那么它能够播放音乐吗,今天这篇我们文章我们就一起来学习怎样使用使用蜂鸣器来播放音乐,也就是怎样成为一个音乐播放器。 1、蜂鸣器的类型 在设计的时候…...
InnoDB存储引擎(1)
InnoDB存储引擎的优点 InnoDB在设计时考虑到了处理大数据量时的性能,支持事务,回滚和崩溃修复的能力,通过多版本并发控制来减少锁定(降低了锁的争用),同时还支持外键的约束;通过缓冲池在内存中缓存数据来提高查询的性能ÿ…...
VMWare虚拟机共享主机的网络访问外网
1.主机中启动客户端并连接外网 2.设置虚拟网络类型为NAT 3.启动虚拟并通过主机访问外网...
LeetCode Easy|【415. 字符串相加】
力扣题目链接 题目本身难度不大,但是后续的一些补充内容还是值得搞清楚的 主要的逻辑如下: 其实本题的目的就是让我们来模拟我们的竖式加法。所以很直观的一个想法就是使用双指针:分别指向两个 num 的末尾。随后就会产生一些问题:…...
RAG 革命:NVIDIA 工作站如何成为企业 AI 的秘密武器
在深圳的一家科技初创公司,首席技术官李梅正在向她的团队展示一个令人兴奋的新项目。“看这个,” 她指着屏幕上的实时演示说,“我们刚刚用公司的技术文档训练了一个 AI 助手,它现在可以回答任何关于我们产品的问题,而且…...
九大原则,轻松构建个人高效SOP
1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!) 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景,目标,愿景 C - Complication 冲突 讲卡点,讲冲突 Q - Question 疑问-问题 这些冲…...
Airtest的demo实现多设备并行
Airtest的demo实现多设备并行 它实现是的获取adb连接上的所有设备,然后在每一台设备上跑给定的测试用例,跑完之后生成单机的测试报告,最后再汇总这些单机测试报告的结果,形成汇总(聚合)报告: 同…...
社区养老服务小程序的设计
管理员账户功能包括:系统首页,个人中心,用户管理,服务人员管理,服务产品管理,服务预约管理,服务状态管理,服务退订管理,活动管理,视频管理 微信端账号功能包…...
Interceptor拦截器开发
因为1登录后的接口都需要token验证代码,会出现重复代码;2当前的接口不防刷,会被恶意攻击 所以在controller层增加请求拦截,如果你的token不合法,就不让你做后续的处理了 拦截器的作用是什么 作用: 1、对controller层代码的访问进行拦截,合法的请求,那此层代码就处理,反…...
美团 AIGC产品经理面经(已拿 offer)
背景:211本科毕业,毕业之后在北京一家中型电商公司做了3年商家后台产品经理,目前通过老薛的朋友关系拿到了美团的offer。 目前还有几家在面试流程中,继续加油💪 美团AIGC产品面经-业务面 💥1、自我介绍&a…...
@RequestBody与@RequestParam
RequestBody会将请求体中的数据,转换成对象.最主要的是RequestBody就是要返回Json的字符串!!! RequestParam会从http请求查询参数中提取数据! RequestParam和RequestBody是Spring Framework中用于处理HTTP请求的注解…...
vmware上,虚机经常丢失网卡。导致无法上网。
1、winR 输入 services.msc 2、重启这两个服务。 VMware NAT service和VMware DHCP service...
git 鉴权失败
这条错误信息通常出现在使用Git进行远程操作时,比如克隆仓库、拉取更新或推送代码。错误的含义是: HTTP Basic: Access denied:访问被拒绝。The provided password or token is incorrect:提供的密码或令牌不正确。Your account …...
[C++] 容器适配器:深入理解Stack与Queue的底层原理
文章目录 容器适配器简介deque的缺陷为什么使用deque作为stack和queue的底层默认容器 stack和queue的简单讲解Stack(栈)栈的操作图示栈的相关接口 Queue(队列) Stack和Queue的模拟实现Stack(栈)作为容器适配…...
Eclipse maven 的坑
在使用 eclipse 时, eclipse 的右下角 一直在提示 “JPA java change event handler” ,eclipse使用起来很卡,解决办法 问题描述: 在使用 eclipse时, eclipse 的右下角 一直在提示 “JPA java change event handler”…...
多模态视觉大语言模型——LLaVA
论文题目:Visual Instruction Tuning 论文地址:https://arxiv.org/abs/2304.08485 github: https://github.com/haotian-liu/LLaVA 1. Abstract 本文首次尝试使用GPT-4生成多模态指令数据,并基于这些数据训练了LLaVA(Large Language and Vision Assistant)模型,这是一种结…...
服务注册到nacos上,不能点击下线的问题处理
nacos不能下线: 修改 /usr/local/mid/nacos/data 文件夹下 protocol 文件重命名为 protocol_bak,然后再重启nacos nacos单机启动命令:cd sh startup.sh -m standalone nginx启动命令:cd /usr/local/mid/nginx/sbin ./…...
未来3-5年,哪些工作会被AI取代
一篇由高盛经济学家约瑟夫布里格斯 (Joseph Briggs)和德维西科德纳尼 (Devesh Kodnani)撰写的报告指出,全球预计将有3亿个工作岗位被生成式AI取代。 报告称:“最近出现的生成式人工智能将降低劳动力成本和…...
鸿蒙系统开发【网络管理】
网络管理 介绍 此Demo展示如何查询网络详情、域名解析、网络状态监听等功能。 效果预览: 使用说明: 1.启动应用,在点击检查网络、网络详情、网络连接信息后,展示对应的信息; 2.在域名解析的模块下,输入…...
nginx如何处理请求
nginx如何处理请求 注:内容翻译自Nginx官网文档 How nginx processes a request。 基于名称的虚拟服务器 nginx首先要决定哪个服务器应该处理请求。让我们从一个简单的配置开始,三个虚拟服务器都监听在端口*:80: server {listen 80;server_name e…...
EN50155以太网交换机的X键位M12插座在PCB板上同一高度方法
在轨道交通车载EN50155以太网交换机的PCB设计中,X键位M12插座(千兆/万兆接口)常需多个并排或阵列布局。由于X编码插座引脚数较多(8芯)且结构复杂,确保所有插座在PCB板上的同一高度(共面性&#…...
终极指南:深入解析Material Library架构与模块依赖关系
终极指南:深入解析Material Library架构与模块依赖关系 【免费下载链接】material A library to bring fully animated Material Design components to pre-Lolipop Android. 项目地址: https://gitcode.com/gh_mirrors/mate/material Material Library是一…...
如何快速实现Blade框架国际化:多语言和本地化的完整指南
如何快速实现Blade框架国际化:多语言和本地化的完整指南 【免费下载链接】blade :rocket: Lightning fast and elegant mvc framework for Java8 项目地址: https://gitcode.com/gh_mirrors/bl/blade Blade是一款基于Java8的轻量级MVC框架,以其闪…...
魔兽世界游戏插件开发从入门到实战:工具详解与效率提升指南
魔兽世界游戏插件开发从入门到实战:工具详解与效率提升指南 【免费下载链接】wow_api Documents of wow API -- 魔兽世界API资料以及宏工具 项目地址: https://gitcode.com/gh_mirrors/wo/wow_api 作为魔兽世界玩家,你是否曾想过通过自定义插件提…...
西门子S7-1200 PLC如何通过EtherCat转Profinet网关实现高效IO控制?5步搞定配置
西门子S7-1200 PLC与EtherCat设备的高效集成:5步实现Profinet网关配置 在工业自动化领域,不同协议设备之间的无缝通信一直是工程师面临的挑战。当您需要将EtherCat设备接入西门子S7-1200 PLC的Profinet网络时,协议转换网关成为关键桥梁。本文…...
DAC高速线缆市场洞察:预计到2032年将增长至180.8亿元
据恒州诚思调研统计,2025年全球DAC高速线缆市场规模达66.60亿元,预计到2032年将增长至180.8亿元,2026-2032年复合增长率(CAGR)为14.7%。作为数据中心短距离互连的核心组件,DAC高速线缆凭借其低延迟、高可靠…...
js06----流程控制
目录 2.4.1、顺序流程控制 2.4.2、分支流程控制 (1)if分支语句(条件判断语句) (2)if....else...语句 需求1: 需求2: (3)if...else if...else语句&…...
Webots仿真实战:如何用C语言控制四轮小车实现自动行驶
Webots仿真实战:C语言控制四轮小车自动行驶全攻略 引言 在机器人开发领域,仿真环境的重要性不言而喻。它不仅能大幅降低硬件成本,还能加速开发周期,让开发者专注于算法和控制逻辑的优化。Webots作为一款专业的机器人仿真软件&…...
WPF图片处理避坑指南:Image控件Stretch属性的4种模式详解(含效果对比图)
WPF图片处理避坑指南:Image控件Stretch属性的4种模式详解 刚接触WPF开发的工程师们,是否经常遇到图片显示变形、比例失调的困扰?Image控件的Stretch属性看似简单,却藏着不少设计哲学。今天我们就来彻底拆解这个影响图片显示效果的…...
如何让Windows任务栏焕然一新?TranslucentTB给你答案
如何让Windows任务栏焕然一新?TranslucentTB给你答案 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 您是否曾对Windows系统一…...
