电子技术课程设计基于FPGA的音乐硬件演奏电路的设计与实现

news2024/11/27 14:27:56

wx供重浩:创享日记
对话框发送:乐曲电路
免费获取完整无水印论文报告(包含电路图)


文章目录

    • 一、设计任务要求
    • 二、总体框图
    • 三、选择器件
    • 四、功能模块
    • 五、总体设计电路图
    • 六、结束语


一、设计任务要求

1、课程设计题目
设计一个乐曲演奏电路,能够自动播放编写好的音乐。要求将音乐通过实验箱上的喇叭播放出来,用发光二级管显示出乐曲的节拍。
(附加功能:本设计在题目所要求的功能全部实现的基础之上又添加了许多附加功能,所有的功能将在“工程设计总述”中阐明,特此声明。)

2、设计分析
(1) 音乐硬件演奏电路基本原理
硬件电路的发声原理,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制FPGA芯片某个引脚输出一定频率的矩形波,接上扬声器就能发出相应频率的声音。乐曲中的每一音符对应着一个确定的频率,要想FPGA发出不同音符的音调,实际上只要控制它输出相应音符的频率即可。乐曲都是由一连串的音符组成,因此按照乐曲的乐谱依次输出这些音符所对应的频,就可以在扬声器上连续地发出各个音符的音调。而要准确地演奏出一首乐曲,仅仅让扬声器能够发生是不够的,还必须准确地控制乐曲的节奏,即乐曲中每个音符的发生频率及其持续时间是乐曲能够连续演奏的两个关键因素。

(2) 音符频率的获得
多个不同频率的信号可通过对某个基准频率进行分频器获得。由于各个音符的频率多为非整数,而分频系数又不能为小数,故必须将计算机得到的分频系数四舍五入取整。若基准频率过低,则分频系数过小,四舍五入取整后的误差较大。若基准频率过高,虽然可以减少频率的相对误差,但分频结构将变大。实际上应该综合考虑这两个方面的因素,在尽量减少误差的前提下,选取合适的基准频率。本设计中选取1MHz的基准频率。数控分频器采用12位二进制计数器,乐曲中的休止符,只要将分频系数设为0,即初始值=4095,此时扬声器不会发声。

根据分频系数,可计算数控分频器得到的初始值。(语言已经无法描述其中的原理了,程序可以说明此问题,关于初始值的解释,请看下文给出的程序)
初始值的计算公式如下:由于所设计的数控分频计采用12MHZ作为时钟源,并通过一次12分频给出频率为1MHZ的脉冲溢出信号,再对该1MHZ的溢出信号进行12位2进制码的带预置数进行计数,并给出一个频率随预置数变化的脉冲信号。由于该脉冲信号不具有驱动蜂鸣器的能力,故对此脉冲信号进行2分频以推动蜂鸣器发声,故最终输出信号的频率与预置数的关系如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(3) 乐曲节奏的控制
一般乐曲最小的节拍为1/4拍,若将1拍的时间定为1秒,则只需要输出4Hz的1/4拍的时长(0.25秒),对于其它占用时间较长的节拍(必为1/4拍的整数倍)则只需要将该音符连续输出相应的次数即可。
计数时钟信号作为输出音符快慢的控制信号,时钟快时输出节拍速度就快,演奏的速度也就快,时钟慢时输出节拍的速度就慢,演奏的速度自然降低,由于最后的蜂鸣器前需加一个二分频的程序,因此计数器的时钟信号应为4Hz的2倍,即8Hz。

(4) 乐谱的发生
本设计将乐谱中的音符数据存储在LPM-ROM中,若某音在逻辑中停留了4个时钟节拍,即1秒的时间,相应地,该音符就要在LPM-ROM中连续的四个地址上都存储。当一个4Hz的时钟来时,相应地就从LPM-ROM中输出一个音符数据。

(5) 选择模块
选择模块将用一个4位数的控制信号控制乐谱模块数据的选择性,用vhdl语言描述比较简单,不在此详述。

(6)译码器等其他模块
译码器等模块在以前做实验的时候做过,且原理比较简单易懂,不再这里阐述。

3、工程设计总述
当一个4Hz的时钟脉冲来到时,乐谱发生器模块输出一个音符数据给分频系数模块,分频系数模块输出此音符相应的分频系数所需的初始值,将初始值送给数控分频器模块,当12MHz的时钟脉冲来到时,数控分频器就根据分频系数输出相应的频率(即此音符所对应的发生频率)给扬声器,扬声器就可发出对应音符的声音来.连续的8Hz的时钟脉冲就将乐谱发生器里所存储的音符数据一个接一个的送给了分频系数模块,再经过数控分频模块,最后扬声器一个接一个的发出音符数据所对应的声音来。曲子也就流畅的播放出来了。同时led数码管会随着音乐显示相应的乐谱,3位led灯会随着高中低的频率,相应的闪烁。当乐曲一遍演奏完成后,乐曲发生器能自动从头开始循环演奏,这时用拨码开关选择播放的乐曲,拨码开关给选择器一个选择信号,即可选择相应的歌曲莫开中的数据进入数据翻译模块,播放出相应的歌曲,本工程选取了四首乐曲,以格雷码的形式编码,每次只变一位拨码开关,比较方便选择。(其余完整详见下载)


二、总体框图

在这里插入图片描述
该工程由是个模块构成,其中有四个为乐谱储存模块ROM,如图所示。

1、分频器的功能是将芯片上提供的50MHz的时钟分频为12MHz和8Hz的时钟,分别供计数器与分频驱动器(数控分频器)使用。
2、计数器完成计数功能,183进制(最长的歌曲菊花台有183个字符)每个时钟沿加一。
3、四个音乐模块分别记录了4首歌的乐谱。根据上一模块计数器所计的数读取相应地址里的数据传递给下一模块。
4、选择器完成选择歌曲的功能。
5、数据翻译模块将选择器所选择的歌曲rom里的地址的数据翻译成分频驱动器(数控分频器)分频所需的控制数据、3个led灯数据(高中低音)、以及译码器所需的数据。
6、分频驱动器也就是一个数控分频器,完成分频的功能,并驱动蜂鸣器。
7、译码器将乐谱数据在led数码管上显示。


三、选择器件

详见下载


四、功能模块

1.分频器(div)
将芯片上提供的50MHz的时钟分频为12MHz和8Hz的时钟,分别供计数器与分频驱动器(数控分频器)使用。

(1)模块图形:
在这里插入图片描述
(2)程序如下:

LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY div IS
   PORT(
       clk :IN STD_LOGIC; 
       CLK12MHz,CLK8Hz: OUT std_logic);
END div;
ARCHITECTURE  one of div is
begin
nana:process(clk)
variable cnt:integer range 0 to 2;
variable tmp:std_logic;
begin
if(clk'event and clk='1')then
if cnt>=1 then
cnt:=0;
tmp:=not tmp;
else
cnt:=cnt+1;
end if;
end if;
CLK12MHz<=tmp;
end process nana;
nbnb:process(clk)
variable cnt:integer range 0 to 3125000;
variable tmp:std_logic;
begin
if(clk'event and clk='1')then
if cnt>=3124999 then
cnt:=0;
tmp:=not tmp;
else
cnt:=cnt+1;
end if;
end if;
CLK8Hz<=tmp;
end process nbnb;
end one;

(3)仿真波形:
在这里插入图片描述
(4)仿真波形分析
由波形可看出ckl为输入50MHz的时钟信号,ckl12输出为平12MHz的时钟信号,clk8为8Hz的时钟信号,由于纸张有限没有打印出其全部波形。
经分析该模块功能完全正确。

2、计数器(notetabs)
(详见下载)

3、选择模块(choice)
(详见下载)

4、数据翻译模块(tontaba)

将选择器所选择的歌曲rom里的地址的数据翻译成分频驱动器(数控分频器)分频所需的控制数据、3个led灯数据(高中低音)、以及译码器所需的数据。

(1)模块图像:
在这里插入图片描述
(2)程序如下:

library ieee;
use ieee.std_logic_1164.all;
entity tonetaba is
  port(index:in std_logic_vector (4 downto 0);
    code:out std_logic_vector(3 downto 0);
    high0:out std_logic_vector(2 downto 0);
    tone:out std_logic_vector(11 downto 0))
;
  end;
architecture one of tonetaba is
begin
search:process(index)
begin
  case index is
when"00000"=>tone<="111111111111";code<="0000";high0<="000";--0/4095
when"00001"=>tone<="011100011111";code<="0001";high0<="001";--L1/1823
when"00010"=>tone<="100000001111";code<="0010";high0<="001";--L2/2063
when"00011"=>tone<="100011110010";code<="0011";high0<="001";--L3/2291
when"00100"=>tone<="100101010101";code<="0100";high0<="001";--L4/2390
when"00101"=>tone<="101000010000";code<="0101";high0<="001";--L5/2576
when"00110"=>tone<="101010111000";code<="0110";high0<="001";--L6/2745
when"00111"=>tone<="101101001011";code<="0111";high0<="001";--L7/2891
when"01000"=>tone<="101110001111";code<="0001";high0<="010";--M1/2960
when"01001"=>tone<="110000001001";code<="0010";high0<="010";--M2/3082
when"01010"=>tone<="110001111001";code<="0011";high0<="010";--M3/3193
when"01011"=>tone<="110010101100";code<="0100";high0<="010";--M4/3244
when"01100"=>tone<="110100001001";code<="0101";high0<="010";--M5/3337
when"01101"=>tone<="110101011100";code<="0110";high0<="010";--M6/3420
when"01110"=>tone<="110110100101";code<="0111";high0<="010";--M7/3494
when"01111"=>tone<="110111000111";code<="0001";high0<="100";--H1/3528
when"10000"=>tone<="111000000101";code<="0010";high0<="100";--H2/3589
when"10001"=>tone<="111000111100";code<="0011";high0<="100";--H3/3645
when"10010"=>tone<="111001010110";code<="0100";high0<="100";--H4/3670
when"10011"=>tone<="111010000100";code<="0101";high0<="100";--H5/3717
when"10100"=>tone<="111010101101";code<="0110";high0<="100";--H6/3758
when"10101"=>tone<="111011010010";code<="0111";high0<="100";--H7/3795
when others=>null;
  end case;
  end process;
  end;

(3)仿真波形:
在这里插入图片描述
(4)仿真波形分析

由波形可看出,当输入信号index为00110时high0显示1,code显示6(即 中音6),预置初值为101010111000,查询上文所列的表,可发现功能完全正确。

第二个波形图,输入信号00010,输出为中音2,再查预置初值,同样可发现完全正确。因此该模块功能完全正确。

5、译码器模块(deled)
(详见下载)

6、数控分频器模块(speakera)
(详见下载)

7、乐谱数据ROM(四个模块)
(详见下载)

8、地址线的选择:
除了上文所写到的模块外,还需要加入地址线的选择,已选择实验底箱的不同功能,本实验用到led数码管,因此地址线vga的赋值为vga0=0,vga1=1,vga2=0,vga3=0。如下图:

在这里插入图片描述

9、led数码管位选功能的解决方案:
本工程只需显示一位简朴,因此选用一位数码管即可,由于实验箱上的数码管是共阳数码管,因此只需选取一位数码管赋上低电平即可,如图:(我在这里选取了2、4、6、8四位数码管共同显示)

在这里插入图片描述


五、总体设计电路图

1、顶层设计的电路原理图

在这里插入图片描述
2、顶层设计的仿真结果
由于该工程总体的输入时钟信号为50MHz,其中要经过多个分频器且分频系数巨大,因此不可能整体仿真成功,(会导致仿真时间过长而失败)。关于这个问题,我特意请教了李兵老师,老师告诉我仿真的时候去掉几个模块,只仿真一部分功能,去掉的模块再单独仿真即可证明整个工程的正确性,我按这个方案想了很久,发现这个仿真可以先去掉div分频模块,再更改speakera的程序(像仿真speakera模块那样)仿真,也可以同时去掉div与speakera模块,进行仿真。但这两种方法也都是拆分为几块分别仿真,而没有整个工程的仿真,因此这种仿真与将每个模块分别仿真验证其功能的正确性本质上是一样的。
只要证明了每个模块的功能完全正确,即可得出本工程整体的功能可以实现,在上文已经分别证明了每个模块功能的完全正确,因此,整个工程的功能也是完全正确的。经分析,顶层设计仿真功能完全正确。

3、电路的顶层文件管脚分配图如下

在这里插入图片描述
4、连线及下载
在硬件电路上实现此程序 CLK接50MHz晶振输入;音乐选择指示灯分别接IO9、I010、IO11、IO12,然后再与LED灯连接;高中低音分别接IO14、IO15、IO16,然后再与LED连接,SPKOUT接IO13,然后与扬声器连接。


六、结束语

乐曲演奏广泛用于自动答录装置、手机铃声、集团电话、及智能仪器仪表设备。实现方法有许多种,在众多的实现方法中,以纯硬件完成乐曲演奏,随着FPGA集成度的提高,价格下降,EDA设计工具更新换代,功能日益普及与流行,使这种方案的应用越来越多。如今的数字逻辑设计者面临日益缩短的上市时间的压力,不得不进行上万门的设计,同时设计者不允许以牺牲硅的效率达到保持结构的独特性。使用现今的EDA软件工具来应付这些问题,并不是一件简单的事情。FPGA预装了很多已构造好的参数化库单元LPM器件。通过引入支持LPM的EDA[1]软件工具,设计者可以设计出结构独立而且硅片的使用效率非常高的产品。
这种基于FPGA的音乐硬件演奏电路的设计与实现,不仅通过VHDL层次化和模块化设计方法,同时采用数控分频和定制LPM-ROM的设计思想,更好的优化了乐曲演奏数字电路的设计,在此基础上不必变化顶层文件架构可随意变更乐曲,有效缩短了产品开发周期、减少了设计芯片的数量、降低了功耗、提高了设计的灵活性、可靠性和可扩展性。

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

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

相关文章

【Flutter从入门到入坑之三】Flutter 是如何工作的

【Flutter从入门到入坑之一】Flutter 介绍及安装使用 【Flutter从入门到入坑之二】Dart语言基础概述 【Flutter从入门到入坑之三】Flutter 是如何工作的 本文章主要以界面渲染过程为例&#xff0c;介绍一下 Flutter 是如何工作的。 页面中的各界面元素&#xff08;Widget&…

使数组和能被P整除[同余定理+同余定理变形]

同余定理同余定理变形前言一、使数组和能被P整除二、同余定理变形总结参考资料前言 同余定理非常经典&#xff0c;采用前缀和 map&#xff0c;当两个余数前缀和为一个值时&#xff0c;则中间一段子数组刚好对P整除。但是能否找到前面是否有一段子数组和可以对P整除呐&#xf…

认识CSS之元素显示模式

&#x1f31f;所属专栏&#xff1a;前端只因变凤凰之路&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该系列将持续更新前端的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&#x1f449;文章简…

深度学习训练营之数据增强

深度学习训练营学习内容原文链接环境介绍前置工作设置GPU加载数据创建测试集数据类型查看以及数据归一化数据增强操作使用嵌入model的方法进行数据增强模型训练结果可视化自定义数据增强查看数据增强后的图片学习内容 在深度学习当中,由于准备数据集本身是一件十分复杂的过程,…

Python 中 KeyError: 0 exception 错误

Python “KeyError: 0” 异常是在我们尝试访问不包含0 这个键的时候去访问该键而引起的。 要解决该错误&#xff0c;请在尝试访问字典之前在字典中设置键&#xff0c;或者如果键不存在&#xff0c;则使用 dict.get() 获取默认值。 下面是一个产生上述错误的示例 my_dict {1…

KDZD互感器二次负载测试仪

一、概述 电能计量综合误差过大是电能计量中普遍存在的一个关键问题。电压互感器二次回路压降引起的计量误差往往是影响电能计量综合误差的因素。所谓电压互感器二次压降引起的误差&#xff0c;就是指电压互感器二次端子和负载端子之间电压的幅值差相对于二次实际电压的百分数…

五分钟了解JumpServer V2.* 与 v3 的区别

一、升级注意项 1、梳理数据。JumpServer V3 去除了系统用户功能&#xff0c;将资产与资产直接绑定。当一个资产名下有多个同名账号&#xff0c;例如两个root用户时&#xff0c;升级后会自动合并最后一个root&#xff0c;不会同步其他root用户。升级前需保证每一个资产只拥有一…

即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示

结论先行 原则&#xff1a; server拉取的消息一定是连续的原则&#xff1a; 端侧记录的消息的连续段有两个作用&#xff1a; 1. 记录消息的连续性&#xff0c; 即起始中间没有断层&#xff0c; 2. 消息连续&#xff0c; 同时意味着消息是最新的&#xff0c;消息不是过期的。同…

Java学习-MySQL-创建数据库表

Java学习-MySQL-创建数据库表 SHOW DATABASESUSE school CREATE TABLE IF NOT EXISTS student( id INT(10) NOT NULL AUTO_INCREMENT COMMENT 学号, name VARCHAR(30) NOT NULL DEFAULT 匿名 COMMENT 姓名, pws VARCHAR(20) NOT NULL DEFAULT 123456 COMMENT 密码, sex VARCHA…

算法题--二叉树(判断是不是平衡二叉树、二叉树的中序遍历、二叉树最大深度、对称二叉树、合并二叉树)

目录 二叉树 题目 判断是不是平衡二叉树 题链接 解析 核心思想 答案 二叉树的中序遍历 原题链接 解析 核心思想 答案 二叉树最大深度、对称二叉树、合并二叉树 二叉树 该类题目的解决一般是通过节点的遍历去实现&#xff0c;一般是分两种。 一是递归&#xff08;…

【记录】日常|shandianchengzi的三周年创作纪念日

机缘 接触 CSDN 之前&#xff0c;我已经倒腾过 hexo 搭建 github 博客、本地博客、图床&#xff1b;   接触 CSDN 之后&#xff0c;我还倒腾过纸质笔记、gitee 博客、博客园、知乎、b站、Notion、腾讯文档、有道云笔记、XMind、飞书文档、简书等一系列创作平台&#xff0c;但…

SAPUI5开发01_01-Installing Eclipse

1.0 简要要求概述: 本节您将安装SAPUI 5,以及如何在Eclipse Juno中集成SAPUI 5工具。 1.1 安装JDK JDK 是一种用于构建在 Java 平台上发布的应用程序、Applet 和组件的开发环境,即编写 Java 程序必须使用 JDK,它提供了编译和运行 Java 程序的环境。 在安装 JDK 之前,首…

1635_fileno的简单使用

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 在看MIT的OS课程的时候发现自己动不动就因为只是的缺少而卡住&#xff0c;而这个学习占据了我工作之余很多的时间。现在都有一点觉得通关不了的感觉了&#xff0c;…

1. Qt Designer Studio界面介绍

1. 说明&#xff1a; Qt当中的Qt Quick框架使用QML语言来快速搭建优美的界面&#xff0c;但是对于单纯做界面的设计人员并不是很友好&#xff0c;还要让界面设计人员去消耗时间成本学习QML语法。Qt Designer Studio软件就是为了解决这个问题而设计的&#xff0c;工作人员不需要…

【Blender】Stability AI插件 - AI生成图像和动画

Stability AI 的官方插件允许 Blender 艺术家使用现有的项目和文本描述来创建新的图像、纹理和动画。 推荐&#xff1a;用 NSDT场景设计器 快速搭建3D场景。 1、安装Stability for Blender插件 首先&#xff0c;从这里下载最新版本的 Blender&#xff0c;然后转到 Addon Relea…

论文阅读笔记|大规模多标签文本分类

多标签文本分类&#xff08;Extreme Multi Label Classification, MLTC&#xff09;是自然语言处理领域中一个十分重要的任务&#xff0c;其旨在从一个给定的标签集合中选取出与文本相关的若干个标签。MLTC可以广泛应用于网页标注&#xff0c;话题识别和情感分析等场景。大规模…

1636_isatty函数的功能

全部学习汇总&#xff1a; GreyZhang/g_unix: some basic learning about unix operating system. (github.com) 前面刚刚看完了一个函数和三个文件指针&#xff0c;一行代码懂了半行。但是继续分析我之前看到的代码还是遇到了困难&#xff0c;因为之前自己对于UNIX的一些基础知…

网络协议(十四):WebSocket、WebService、RESTful、IPv6、网络爬虫、HTTP缓存

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 网络…

Kubernetes(K8s)接入Prometheus示例、查看指标

Prometheus安装关联服务见&#xff1a;https://blog.csdn.net/lsc_2019/article/details/129445580?spm1001.2014.3001.5502 在Kubernetes中创建一个Deployment和一个Service apiVersion: apps/v1 kind: Deployment metadata:name: myapp spec:replicas: 3selector:matchLabe…

Jackson 返回前端的 Response结果字段大小问题

目录 1、问题产生的背景 2、出现的现象 3、解决方案 4、成果展现 5、总结 6、参考文章 1、问题产生的背景 因为本人最近工作相关的对接外部项目&#xff0c;在我们国内有很多程序员都是使用汉语拼音或者部分字母加上英文复合体定义返回实体VO&#xff0c;这样为了能够符合…