于FPGA音乐硬件演奏电路设计.docx

上传人:b****1 文档编号:12523030 上传时间:2023-04-19 格式:DOCX 页数:58 大小:243.73KB
下载 相关 举报
于FPGA音乐硬件演奏电路设计.docx_第1页
第1页 / 共58页
于FPGA音乐硬件演奏电路设计.docx_第2页
第2页 / 共58页
于FPGA音乐硬件演奏电路设计.docx_第3页
第3页 / 共58页
于FPGA音乐硬件演奏电路设计.docx_第4页
第4页 / 共58页
于FPGA音乐硬件演奏电路设计.docx_第5页
第5页 / 共58页
点击查看更多>>
下载资源
资源描述

于FPGA音乐硬件演奏电路设计.docx

《于FPGA音乐硬件演奏电路设计.docx》由会员分享,可在线阅读,更多相关《于FPGA音乐硬件演奏电路设计.docx(58页珍藏版)》请在冰豆网上搜索。

于FPGA音乐硬件演奏电路设计.docx

于FPGA音乐硬件演奏电路设计

摘要

根据国家教委与专业教学委员会对教育机构的要求,为培养适应我国21世纪国民经济发展需要的电子设置人才;同时基于国家教委面向21世纪电工电子课程体系改革和电工电子工科教学基地建设两项教学改革研究成果。

要求高等专科学校学生能够自己动手完成简单数字器件的设计。

这不但反应了我国当前在电子电路的实验教学体系、内容和方法上的改革思路和教学水平的提高,更重要的是在加强以传统电子设计方法为基础的工程设计训练的同时,使学生能够尽快掌握现代电子设计自动化技术的新方法、新工具和新手段系统的、科学的培养了学生的实际动手能力、理论联系实际的能力、工程设计能力,创新能力,提高了学生对基础实验的兴趣。

本次设计在EDA开发平台QUARTUSII6.0上利用VHDL语言设计数控分频器电路,利用数控分频的原理设计音乐硬件演奏电路,并定制LPM-ROM存储音乐数据,以“梁祝”和“月亮代表我的心”两首乐曲为例,将音乐数据存储到LPM-ROM,就达到了以纯硬件的手段来实现乐曲的演奏效果。

只要修改LPM-ROM所存储的音乐数据,将其换成其他乐曲的音乐数据,再重新定制LPM-ROM,连接到程序中就可以实现其它乐曲的演奏。

本设计采用的是武汉理工大学的开放设计实验箱,FPGA目标芯片型号为Altera公司的Cyclone系列中的EP1C3T144C8N。

芯片配置成功后即可进行硬件测试:

选择实验电路结构图,发音输出接SPEAKER,当乐曲一遍演奏完成后,乐曲发生器能自动从头开始循环演奏。

关键词:

FPGA/CPLD,音乐硬件演奏电路,VHDL语言设计,QUARTUSII6.0

1系统设计总述

1.1设计要求

这是一种运用纯硬件实现乐曲播放的电路,比运用微处理器实现乐曲播放更加复杂。

它运用了强大功能的EDA工具——开放设计试验箱和硬件描述语言VHDL。

本课题以歌曲《妈妈的吻》来实现乐曲播放电路的功能。

(1)顺序播放乐曲功能:

当电路开始工作时,如果存储器中有多首乐曲,那么演奏电路将从头到尾顺序播放这些乐曲。

(2)循环播放乐曲功能:

当演奏完后一首乐曲时,将自动返回到第一首歌曲开始播放,反复不止,直到关闭电源电路停止工作为止。

(3)乐曲简谱显示功能:

当演奏电路播放乐曲时,能够将当前播放的音符通过一列发光二极管以二进制的形式予以显示。

(4)乐曲高音显示功能:

如果电路正在播放高音音符,那么将有一个发光二极管点亮来显示。

(5)音量大小可调功能:

运用EDA实验箱上的数字功率放大器LM386N,对数控分频器输出的音频信号予以处理,输出大小连续可调的音频信号到扬声器。

1.2系统组成

(1)音乐硬件演奏电路基本原理

硬件电路的发声原理,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制FPGA芯片某个引脚输出一定频率的矩形波,接上扬声器就能发出相应频率的声音。

乐曲中的每一音符对应着一个确定的频率,要想FPGA发出不同音符的音调,实际上只要控制它输出相应音符的频率即可。

乐曲都是由一连串的音符组成,因此按照乐曲的乐谱依次输出这些音符所对应的频,就可以在扬声器上连续地发出各个音符的音调。

而要准确地演奏出一首乐曲,仅仅让扬声器能够发生是不够的,还必须准确地控制乐曲的节奏,即乐曲中每个音符的发生频率及其持续时间是乐曲能够连续演奏的两个关键因素。

(2)音符频率的获得

多个不同频率的信号可通过对某个基准频率进行分频器获得。

由于各个音符的频率多为非整数,而分频系数又不能为小数,故必须将计算机得到的分频系数四舍五入取整。

若基准频率过低,则分频系数过小,四舍五入取整后的误差较大。

若基准频率过高,虽然可以减少频率的相对误差,但分频结构将变大。

实际上应该综合考虑这两个方面的因素,在尽量减少误差的前提下,选取合适的基准频率。

本设计中选取750KHz的基准频率。

由于现有的高频时钟脉冲信号的频率为12MHz,故需先对其进行16分频,才能获得750KHz的基准频率。

对基准频率分频后的输出信号是一些脉宽极窄的尖脉冲信号(占空比=1/分频系数)。

为提高输出信号的驱动能力,以使扬声器有足够的功率发音,需要再通过一个分频器将原来的分频器的输出脉冲均衡为对称方波(占空比=1/2),但这时的频率将是原来的1/2。

下表中各音符的分频系数就是从750KHz的基准频率二分频得到的375KHz频率基础上计算得到的。

由于最大分频系数是1274,故分频器采用11位二进制计数器能满足要求,乐曲中的休止符,只要将分频系数设为0,即初始值=211-1=2047,此时扬声器不会发声。

表1各个音符的频率及其对应的分频系数(基准频率375KHz)

音符名

频率(Hz)

分频系数

计数初值

音符名

频率(Hz)

分频系数

计数初值

休止符

375000

0

2047

中音4

796.178

468

1579

低音1

294.349

1274

773

中音5

882.353

425

1622

低音2

330.396

1135

912

中音6

989.446

379

1668

低音3

370.92

1011

1036

中音7

1136.363

330

1717

低音4

386.598

970

1077

高音1

1175.549

319

1728

低音5

394.737

950

1197

高音2

1353.790

277

1770

低音6

495.376

757

1290

高音3

1512.097

248

1799

低音7

555.56

675

1372

高音4

1609.442

233

1814

中音1

588.697

637

1410

高音5

1802.884

208

1839

中音2

638.84

587

1480

高音6

2027.027

185

1862

中音3

742.574

505

1542

高音7

2272.727

165

1882

(3)乐曲节奏的控制

本设计中的梁祝和月亮代表我的心的乐曲,最小的节拍为1/4拍,若将1拍的时间定为1秒,则只需要提供一个4Hz的时钟频率即可产生1/4拍的时长(0.25秒),对于其它占用时间较长的节拍(必为1/4拍的整数倍)则只需要将该音符连续输出相应的次数即可。

计数时钟信号作为输出音符快慢的控制信号,时钟快时输出节拍速度就快,演奏的速度也就快,时钟慢时输出节拍的速度就慢,演奏的速度自然降低。

(4)乐谱发生器

本文将乐谱中的音符数据存储在LPM-ROM中,如“梁祝”乐曲中的第一个音符为“3”,此音在逻辑中停留了4个时钟节拍,即1秒的时间,相应地,音符“3”就要在LPM-ROM中连续的四个地址上都存储。

当一个4Hz的时钟来时,相应地就从LPM-ROM中输出一个音符数据。

(5)音乐硬件演奏电路总体设计流程

当一个4Hz的时钟脉冲来到时,乐谱发生器模块输出一个音符数据给分频系数模块,分频系数模块输出此音符相应的分频系数,将分频系数送给数控分频器模块,当12MHz的时钟脉冲来到时,数控分频器就根据分频系数输出相应的频率(即此音符所对应的发生频率)给扬声器,扬声器就可发出对应音符的声音来.连续的4Hz的时钟脉冲就将乐谱发生器里所存储的音符数据一个接一个的送给了分频系数模块,再经过数控分频模块,最后扬声器一个接一个的发出音符数据所对应的声音来。

曲子也就流畅的播放出来了,当乐曲一遍演奏完成后,乐曲发生器能自动从头开始循环演奏,按下SEL键时播放第二首歌,按下RST键时从头开始播放歌曲。

音乐硬件演奏电路主要是用VHDL语言来设计,并利用Quartus6.0软件工具来编译、测试和仿真,音乐硬件演奏电路设计总体设计方框图如下图所示。

图1.1音乐硬件演奏电路设计总体设计方框图

2总体程序设计

2.1顶层模块设计流程图

图2.1顶层模块设计流程图

2.2顶层电路VHDL程序设计

LIBRARYIEEE;--硬件演奏电路顶层设计

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYSongerIS

PORT(CLK12MHZ:

INSTD_LOGIC;--音调频率信号

CLK8HZ:

INSTD_LOGIC;--节拍频率用于控制音长(节拍)的时钟频率;

SEL:

INSTD_LOGIC;--音乐选择键

RST:

INSTD_LOGIC;--复位键

CODE1:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);--简谱码输出显示

HIGH1:

OUTSTD_LOGIC;--高8度指示

SPKOUT:

OUTSTD_LOGIC);--声音输出

END;

ARCHITECTUREoneOFSongerIS

COMPONENTNoteTabs--元件U1例换化

PORT(clk:

INSTD_LOGIC;

SEL:

INSTD_LOGIC;

RST:

INSTD_LOGIC;

ToneIndex:

OUTSTD_LOGIC_VECTOR(3DOWNTO0));

ENDCOMPONENT;

COMPONENTToneTaba--元件U2例换化

PORT(Index:

INSTD_LOGIC_VECTOR(3DOWNTO0);

CODE:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);

HIGH:

OUTSTD_LOGIC;

Tone:

OUTSTD_LOGIC_VECTOR(10DOWNTO0));

ENDCOMPONENT;

COMPONENTSpeakera--元件U3例换化

PORT(clk:

INSTD_LOGIC;

Tone:

INSTD_LOGIC_VECTOR(10DOWNTO0);

SpkS:

OUTSTD_LOGIC);

ENDCOMPONENT;

SIGNALTone:

STD_LOGIC_VECTOR(10DOWNTO0);

SIGNALToneIndex:

STD_LOGIC_VECTOR(3DOWNTO0);

BEGIN

u1:

NoteTabsPORTMAP(clk=>CLK8HZ,RST=>RST,SEL=>SEL,ToneIndex=>ToneIndex);--参数传递映射语句

u2:

ToneTabaPORTMAP(Index=>ToneIndex,Tone=>Tone,CODE=>CODE1,HIGH=>HIGH1);

u3:

SpeakeraPORTMAP(clk=>CLK12MHZ,Tone=>Tone,SpkS=>SPKOUT);

END;

3单元模块程序设计

根据顶层原理图,共分为music模块、地址发生器模块、分频预置数模块、十六进制模块、数控分频模块这五个模块。

music模块存放乐曲中的音符数据,地址发生器模块作为music模块中所定制的音符数据ROM的地址发生器,分频预置数模块提供分频预置数即给数控分频模块提供计数初值,十六进制模块对12MHz的时钟脉冲进行16分频,得到750KHz的频率,给数控分频模块提供时钟脉冲。

数控分频模块根据分频预置数输出各个音符所对应的频率。

3.1音乐节拍和音调发生器模块

图3.1音乐节拍和音调发生器模块

(1)音乐节拍和音调发生器模块RTL电路图

图3.2音乐节拍和音调发生器模块RTL电路图

(2)音乐节拍和音调发生器模块VHDL程序设计

LIBRARYIEEE;--音乐节拍和音调发生器模块

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYNoteTabsIS

PORT(clk:

INSTD_LOGIC;--音乐节拍时钟4HZ

SEL:

INSTD_LOGIC;--音乐选择键

RST:

INSTD_LOGIC;--复位键

ToneIndex:

OUTSTD_LOGIC_VECTOR(3DOWNTO0));

END;

ARCHITECTUREoneOFNoteTabsIS

COMPONENTmusic--音符数据ROM1

PORT(address:

INSTD_LOGIC_VECTOR(7DOWNTO0);

clock:

INSTD_LOGIC;

q:

OUTSTD_LOGIC_VECTOR(3DOWNTO0));

ENDCOMPONENT;

SIGNALCounter:

STD_LOGIC_VECTOR(7DOWNTO0);--8位二进制计数器

BEGIN

CNT8:

PROCESS(clk,Counter,sel,rst)

BEGIN

IF((clk'EVENTANDclk='1')and(Counter=256orrst='0'))thenCounter<="00000000";Counter<=Counter+1;

endif;

IF((clk'EVENTANDclk='1')and(sel='0'))THENCounter<="10010000";Counter<=Counter+1;

endif;

ENDPROCESS;

u1:

MUSICPORTMAP(address=>Counter,q=>ToneIndex,clock=>clk);

END;

(2)地址发生器模块

地址发生器模块设置了一个8位二进制计数器(计数最大值为256),作为音符数据ROM的地址发生器。

每来一个时钟脉冲信号(Clk),8位二进制计数器就计数一次,ROM文件中的地址也就随着递增,音符数据ROM中的音符也就一个接一个连续的取出来了。

在地址发生器的VHDL设计中,这个计数器的计数频率选为4Hz,即每一计数值的停留时间为0.25秒,恰为当全音符设为1秒,四四拍的4分音符持续时间。

例如,地址发生器在以下的VHDL逻辑描述中,“梁祝”乐曲的第一个音符为“3”,此音在逻辑中停留了4个时钟节拍,即1秒时间。

那么相应随着程序[4]中的计数器按4Hz的时钟频率作加法计数时,即随地址递增时,将从音符数据ROM中将连续取出4个音符“3”通过toneindex[3..0]端口输向分频预置数模块。

这样梁祝乐曲中的音符就一个接一个的通过toneindex[3..0]端口输向分频预置数模块。

3.2音乐谱对应分频预置数查表电路模块

(1)音乐谱分频预置数模块

图3.3音乐谱分频预置数模块

(2)音乐谱对应分频预制数查表电路VHDL程序设计

音乐谱分频预置数模块是乐曲简谱码对应的分频预置数查表电路。

它提供了每个音符所对应的分频预置数,即给数控分频模块提供计数初值,这里以“梁祝”乐曲为例,列出了在这个乐曲中所用到的13个音符的分频预置数。

在这个模块的VHDL逻辑描述中设置了四四拍乐曲中全部音符所对应的分频预置数,共13个,每一音符的停留时间由音乐节拍和地址发生器模块的时钟(Clk)的输入频率决定,在此为4Hz。

这13个值的输出由程序[3]的4位输入值index[3..0]确定。

输向程序[4]中index[3..0]的值又由地址发生器模块的输出toneindex[3..0]的输出值和持续时间决定。

模块的功能是输出各个音符所对应的分频预置数,即当index是“0000”,tone输出为2047,即休止符的分频预置数;当index是“0101”时,tone输出为1197即低音5的分频预置数;当index是“1111”时,tone输出为1728即高音1的分频预置数等等其它状态时,tone分别输出相应音符的分频预置数。

分频预置数模块的VHDL设计程序如下:

LIBRARYIEEE;--音乐谱对应分频预制数查表电路模块

USEIEEE.STD_LOGIC_1164.ALL;

ENTITYToneTabaIS

PORT(Index:

INSTD_LOGIC_VECTOR(3DOWNTO0);--4位预制数查表

CODE:

OUTSTD_LOGIC_VECTOR(3DOWNTO0);

HIGH:

OUTSTD_LOGIC;--音乐高8度指示

Tone:

OUTSTD_LOGIC_VECTOR(10DOWNTO0));--音乐符对应分频11位

END;

ARCHITECTUREoneOFToneTabaIS

BEGIN

Search:

PROCESS(Index)

BEGIN

CASEIndexIS--译码电路,查表方式,控制音调的预置数13组频率

WHEN"0000"=>Tone<="11111111111";CODE<="0000";HIGH<='0';--2047

WHEN"0001"=>Tone<="01100000101";CODE<="0001";HIGH<='0';--773;

WHEN"0010"=>Tone<="01110010000";CODE<="0010";HIGH<='0';--912;

WHEN"0011"=>Tone<="10000001100";CODE<="0011";HIGH<='0';--1036;

WHEN"0101"=>Tone<="10010101101";CODE<="0101";HIGH<='0';--1197;

WHEN"0110"=>Tone<="10100001010";CODE<="0110";HIGH<='0';--1290;

WHEN"0111"=>Tone<="10101011100";CODE<="0111";HIGH<='0';--1372;

WHEN"1000"=>Tone<="10110000010";CODE<="0001";HIGH<='1';--1410;

WHEN"1001"=>Tone<="10111001000";CODE<="0010";HIGH<='1';--1480;

WHEN"1010"=>Tone<="11000000110";CODE<="0011";HIGH<='1';--1542;

WHEN"1100"=>Tone<="11001010110";CODE<="0101";HIGH<='1';--1622;

WHEN"1101"=>Tone<="11010000100";CODE<="0110";HIGH<='1';--1668;

WHEN"1111"=>Tone<="11011000000";CODE<="0001";HIGH<='1';--1728;

WHENOTHERS=>NULL;

ENDCASE;

ENDPROCESS;

END;

3.3音乐符数控11分频电路模块

3.3音乐谱对应分频预置数查表电路模块

(1)音乐符数控11分频电路模块

图3.4音乐符数控11分频电路模块

(2)音乐符数控11分频电路模块RTL电路图

图3.4音乐符数控11分频电路模块RTL电路图

(3)音乐符数控11分频模块电路VHDL程序设计

音符的频率由数控分频模块获得,这是一个数控分频电路。

它是由一个初值可变的加法计数器构成。

该计数器的模为2047,当计数器记满时,计数器产生一个溢出信号FULL,此溢出信号就是用作发音的频率信号。

在计数器的输入端给定不同的初值,而此预置数就是表1中的计数初值,就可得到不同音符的发音频率信号。

它计满时所需要的计数初值可由下式来表示。

计数初值(Tone)=2047-分频系数

而分频系数又可有下式来求:

分频系数=基准频率/音符的发生频率

低音时Tone值小,分频系数大,溢出信号周期长,扬声器发出的声音低,Tone随音乐的乐谱变化大,自动控制分频比,实现了数控分频,发生信号的频率与音调Tone成正比。

这就是利用数控分频器自动演奏音乐的原理。

时钟(Clk)端输入的是在十六进制模块里对12MHz的信号进行16分频得到的750KHz,750KHz的信号根据分频预置数模块中所提供的计数初值,分别得出相应音符频率的两倍值。

此时从数控分频器中出来的输出信号是脉宽极窄的脉冲式信号,为了有利于驱动扬声器,需另加一个D触发器以均衡其占空比,这时的频率就变为原来的1/2,刚好就是相应音符的频率。

数控分频模块中对Clk输入信号的分频比由11位预置数tone[10..0]决定。

Fout的输出频率将决定每一个音符的音调,这样,分频计数器的预置值tone[10..0]与Fout的输出频率就有了对应关系。

例如在分频预置数模块中若取tone[10..0]=1036,将发出音符为“3”音的信号频率。

音符的频率由数控分频模块VHDL程序如下:

LIBRARYIEEE;--音乐符数控分频电路模块

USEIEEE.STD_LOGIC_1164.ALL;

USEIEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITYSpeakeraIS

PORT(clk:

INSTD_LOGIC;--音调频率信号12MHZ

Tone:

INSTD_LOGIC_VECTOR(10DOWNTO0);--音乐符对应分频11位

SpkS:

OUTSTD_LOGIC);--声音输出

END;

ARCHITECTUREoneOFSpeakeraIS

SIGNALPreCLK,FullSpkS:

STD_LOGIC;

BEGIN

DivideCLK:

PROCESS(clk)

VARIABLECount4:

STD_LOGIC_VECTOR(3DOWNTO0);

BEGIN

PreCLK<='0';--将CLK进行16分频,PreCLK为CLK的16分频

IFCount4>11THENPreCLK<='1';Count4:

="0000";

ELSIFclk'EVENTANDclk='1'THENCount4:

=Count4+1;

ENDIF;

ENDPROCESS;

GenSpkS:

PROCESS(PreCLK,Tone)--11位可预置计数器

VARIABLECount11:

STD_LOGIC_VECTOR(10DOWNTO0);

BEGIN

IFPreCLK'EVENTANDPreCLK='1'THEN

IFCount11=16#7FF#THENCount11:

=Tone;FullSpkS<='1';

ELSECount11:

=Count11+1;FullSpkS<='0';ENDIF;

ENDIF;

ENDPROCESS;

DelaySpkS:

PROCESS(FullSpkS)--将输出再2分频,展宽脉冲,使扬声器有足够功率发音

VARIABLECoun

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 理学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1