当前位置: 首页 > 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…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...