当前位置: 首页 > news >正文

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开发——蜂鸣器实现音乐播放器的设计

一、概述 我们在进行蜂鸣器的学习的时候&#xff0c;总会在想既然蜂鸣器能够发出声音&#xff0c;那么它能够播放音乐吗&#xff0c;今天这篇我们文章我们就一起来学习怎样使用使用蜂鸣器来播放音乐&#xff0c;也就是怎样成为一个音乐播放器。 1、蜂鸣器的类型 在设计的时候…...

InnoDB存储引擎(1)

InnoDB存储引擎的优点 InnoDB在设计时考虑到了处理大数据量时的性能&#xff0c;支持事务&#xff0c;回滚和崩溃修复的能力&#xff0c;通过多版本并发控制来减少锁定(降低了锁的争用),同时还支持外键的约束&#xff1b;通过缓冲池在内存中缓存数据来提高查询的性能&#xff…...

VMWare虚拟机共享主机的网络访问外网

1.主机中启动客户端并连接外网 2.设置虚拟网络类型为NAT 3.启动虚拟并通过主机访问外网...

LeetCode Easy|【415. 字符串相加】

力扣题目链接 题目本身难度不大&#xff0c;但是后续的一些补充内容还是值得搞清楚的 主要的逻辑如下&#xff1a; 其实本题的目的就是让我们来模拟我们的竖式加法。所以很直观的一个想法就是使用双指针&#xff1a;分别指向两个 num 的末尾。随后就会产生一些问题&#xff1a…...

RAG 革命:NVIDIA 工作站如何成为企业 AI 的秘密武器

在深圳的一家科技初创公司&#xff0c;首席技术官李梅正在向她的团队展示一个令人兴奋的新项目。“看这个&#xff0c;” 她指着屏幕上的实时演示说&#xff0c;“我们刚刚用公司的技术文档训练了一个 AI 助手&#xff0c;它现在可以回答任何关于我们产品的问题&#xff0c;而且…...

九大原则,轻松构建个人高效SOP

1、原则一、工作汇报SOP SCQA模型(升职加薪的关键!&#xff09; 清晰定义问题和提出解决方案 类别 关键词 解读 S - Situation 情景 陈述项目背景&#xff0c;目标&#xff0c;愿景 C - Complication 冲突 讲卡点&#xff0c;讲冲突 Q - Question 疑问-问题 这些冲…...

Airtest的demo实现多设备并行

Airtest的demo实现多设备并行 它实现是的获取adb连接上的所有设备&#xff0c;然后在每一台设备上跑给定的测试用例&#xff0c;跑完之后生成单机的测试报告&#xff0c;最后再汇总这些单机测试报告的结果&#xff0c;形成汇总&#xff08;聚合&#xff09;报告&#xff1a; 同…...

社区养老服务小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;服务人员管理&#xff0c;服务产品管理&#xff0c;服务预约管理&#xff0c;服务状态管理&#xff0c;服务退订管理&#xff0c;活动管理&#xff0c;视频管理 微信端账号功能包…...

Interceptor拦截器开发

因为1登录后的接口都需要token验证代码,会出现重复代码;2当前的接口不防刷,会被恶意攻击 所以在controller层增加请求拦截,如果你的token不合法,就不让你做后续的处理了 拦截器的作用是什么 作用: 1、对controller层代码的访问进行拦截,合法的请求,那此层代码就处理,反…...

美团 AIGC产品经理面经(已拿 offer)

背景&#xff1a;211本科毕业&#xff0c;毕业之后在北京一家中型电商公司做了3年商家后台产品经理&#xff0c;目前通过老薛的朋友关系拿到了美团的offer。 目前还有几家在面试流程中&#xff0c;继续加油&#x1f4aa; 美团AIGC产品面经-业务面 &#x1f4a5;1、自我介绍&a…...

@RequestBody与@RequestParam

RequestBody会将请求体中的数据&#xff0c;转换成对象.最主要的是RequestBody就是要返回Json的字符串&#xff01;&#xff01;&#xff01; RequestParam会从http请求查询参数中提取数据&#xff01; RequestParam和RequestBody是Spring Framework中用于处理HTTP请求的注解…...

vmware上,虚机经常丢失网卡。导致无法上网。

1、winR 输入 services.msc 2、重启这两个服务。 VMware NAT service和VMware DHCP service...

git 鉴权失败

这条错误信息通常出现在使用Git进行远程操作时&#xff0c;比如克隆仓库、拉取更新或推送代码。错误的含义是&#xff1a; HTTP Basic: Access denied&#xff1a;访问被拒绝。The provided password or token is incorrect&#xff1a;提供的密码或令牌不正确。Your account …...

[C++] 容器适配器:深入理解Stack与Queue的底层原理

文章目录 容器适配器简介deque的缺陷为什么使用deque作为stack和queue的底层默认容器 stack和queue的简单讲解Stack&#xff08;栈&#xff09;栈的操作图示栈的相关接口 Queue&#xff08;队列&#xff09; Stack和Queue的模拟实现Stack&#xff08;栈&#xff09;作为容器适配…...

Eclipse maven 的坑

在使用 eclipse 时&#xff0c; eclipse 的右下角 一直在提示 “JPA java change event handler” &#xff0c;eclipse使用起来很卡&#xff0c;解决办法 问题描述&#xff1a; 在使用 eclipse时&#xff0c; 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不能下线&#xff1a; 修改 /usr/local/mid/nacos/data 文件夹下 protocol 文件重命名为 protocol_bak&#xff0c;然后再重启nacos nacos单机启动命令&#xff1a;cd sh startup.sh -m standalone nginx启动命令&#xff1a;cd /usr/local/mid/nginx/sbin ./…...

未来3-5年,哪些工作会被AI取代

一篇由高盛经济学家约瑟夫布里格斯 &#xff08;Joseph Briggs&#xff09;和德维西科德纳尼 &#xff08;Devesh Kodnani&#xff09;撰写的报告指出&#xff0c;全球预计将有3亿个工作岗位被生成式AI取代。 报告称&#xff1a;“最近出现的生成式人工智能将降低劳动力成本和…...

鸿蒙系统开发【网络管理】

网络管理 介绍 此Demo展示如何查询网络详情、域名解析、网络状态监听等功能。 效果预览&#xff1a; 使用说明&#xff1a; 1.启动应用&#xff0c;在点击检查网络、网络详情、网络连接信息后&#xff0c;展示对应的信息&#xff1b; 2.在域名解析的模块下&#xff0c;输入…...

nginx如何处理请求

nginx如何处理请求 注&#xff1a;内容翻译自Nginx官网文档 How nginx processes a request。 基于名称的虚拟服务器 nginx首先要决定哪个服务器应该处理请求。让我们从一个简单的配置开始&#xff0c;三个虚拟服务器都监听在端口*:80: server {listen 80;server_name e…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...