论文乐曲硬件演奏电路设计Word格式文档下载.docx
《论文乐曲硬件演奏电路设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《论文乐曲硬件演奏电路设计Word格式文档下载.docx(28页珍藏版)》请在冰豆网上搜索。
总体设计电路图…………………………………………28六:
六:
结束语…………………………………………………………29
乐曲硬件演奏电路设计
1、设计任务要求
1、课程设计题目
设计一个乐曲演奏电路,能够自动播放编写好的音乐。
要求将音乐通过实验箱上的喇叭播放出来,用发光二级管显示出乐曲的节拍。
(附加功能:
本设计在题目所要求的功能全部实现的基础之上又添加了许多附加功能,所有的功能将在“工程设计总述”中阐明,特此声明。
)
2、设计分析
(1)音乐硬件演奏电路基本原理
硬件电路的发声原理,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制FPGA芯片某个引脚输出一定频率的矩形波,接上扬声器就能发出相应频率的声音。
乐曲中的每一音符对应着一个确定的频率,要想FPGA发出不同音符的音调,实际上只要控制它输出相应音符的频率即可。
乐曲都是由一连串的音符组成,因此按照乐曲的乐谱依次输出这些音符所对应的频,就可以在扬声器上连续地发出各个音符的音调。
而要准确地演奏出一首乐曲,仅仅让扬声器能够发生是不够的,还必须准确地控制乐曲的节奏,即乐曲中每个音符的发生频率及其持续时间是乐曲能够连续演奏的两个关键因素。
(2)音符频率的获得
多个不同频率的信号可通过对某个基准频率进行分频器获得。
由于各个音符的频率多为非整数,而分频系数又不能为小数,故必须将计算机得到的分频系数四舍五入取整。
若基准频率过低,则分频系数过小,四舍五入取整后的误差较大。
若基准频率过高,虽然可以减少频率的相对误差,但分频结构将变大。
实际上应该综合考虑这两个方面的因素,在尽量减少误差的前提下,选取合适的基准频率。
本设计中选取1MHz的基准频率。
数控分频器采用12位二进制计数器,乐曲中的休止符,只要将分频系数设为0,即初始值=4095,此时扬声器不会发声。
根据分频系数,可计算数控分频器得到的初始值。
(语言已经无法描述其中的原理了,程序可以说明此问题,关于初始值的解释,请看下文给出的程序)
初始值的计算公式如下:
由于所设计的数控分频计采用12MHZ作为时钟源,并通过一次12分频给出频率为1MHZ的脉冲溢出信号,再对该1MHZ的溢出信号进行12位2进制码的带预置数进行计数,并给出一个频率随预置数变化的脉冲信号。
由于该脉冲信号不具有驱动蜂鸣器的能力,故对此脉冲信号进行2分频以推动蜂鸣器发声,故最终输出信号的频率与预置数的关系如下:
其中
为音阶对应的频率。
表1简谱中的音名与频率的关系
音名
频率/Hz
低音1
261.63
中音1
532.25
高音1
1046.50
低音2
293.67
中音2
587.33
高音2
1174.66
低音3
329.63
中音3
659.25
高音3
1318.51
低音4
349.23
中音4
698.46
高音4
1396.92
低音5
391.99
中音5
783.99
高音5
1567.98
低音6
440
中音6
880
高音6
1760
低音7
493.88
中音7
987.76
高音7
1975.52
表2各音阶频率对应的分频值
分频系数
初始值
7644
547
3822
4369
1911
6280
6810
1381
3405
4786
1270
6921
6067
2124
3034
5157
1517
6674
5727
2464
2864
5327
1432
6759
5102
3089
2551
5640
1256
6935
4545
3646
2273
5918
1137
7054
4050
4141
2025
6166
1013
7178
(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灯会随着高中低的频率,相应的闪烁。
当乐曲一遍演奏完成后,乐曲发生器能自动从头开始循环演奏,这时用拨码开关选择播放的乐曲,拨码开关给选择器一个选择信号,即可选择相应的歌曲莫开中的数据进入数据翻译模块,播放出相应的歌曲,本工程选取了四首乐曲,以格雷码的形式编码,每次只变一位拨码开关,比较方便选择。
分别为:
0001菊花台
0011世上只有妈妈好
0010一剪梅
0110隐形的翅膀
乐谱如下:
、
二、总体框图
该工程由是个模块构成,其中有四个为乐谱储存模块ROM,如图所示。
1、分频器的功能是将芯片上提供的50MHz的时钟分频为12MHz和8Hz的时钟,分别供计数器与分频驱动器(数控分频器)使用。
2、计数器完成计数功能,183进制(最长的歌曲菊花台有183个字符)每个时钟沿加一。
3、四个音乐模块分别记录了4首歌的乐谱。
根据上一模块计数器所计的数读取相应地址里的数据传递给下一模块。
4、选择器完成选择歌曲的功能。
5、数据翻译模块将选择器所选择的歌曲rom里的地址的数据翻译成分频驱动器(数控分频器)分频所需的控制数据、3个led灯数据(高中低音)、以及译码器所需的数据。
6、分频驱动器也就是一个数控分频器,完成分频的功能,并驱动蜂鸣器。
7、译码器将乐谱数据在led数码管上显示。
三、选择器件
1.EP1C12Q240C8芯片
2.实验箱底板电路
(包括蜂鸣器
7段数码管
Led灯7个)
3.计算机
四、功能模块
1.分频器(div)
将芯片上提供的50MHz的时钟分频为12MHz和8Hz的时钟,分别供计数器与分频驱动器(数控分频器)使用。
(1)模块图形:
(2)程序如下:
LIBRARYieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
ENTITYdivIS
PORT(
clk:
INSTD_LOGIC;
CLK12MHz,CLK8Hz:
OUTstd_logic);
ENDdiv;
ARCHITECTUREoneofdivis
begin
nana:
process(clk)
variablecnt:
integerrange0to2;
variabletmp:
std_logic;
if(clk'
eventandclk='
1'
)then
ifcnt>
=1then
cnt:
=0;
tmp:
=nottmp;
else
=cnt+1;
endif;
CLK12MHz<
=tmp;
endprocessnana;
nbnb:
integerrange0to3125000;
=3124999then
CLK8Hz<
endprocessnbnb;
endone;
(3)仿真波形:
(4)仿真波形分析
由波形可看出ckl为输入50MHz的时钟信号,ckl12输出为平12MHz的时钟信号,clk8为8Hz的时钟信号,由于纸张有限没有打印出其全部波形。
经分析该模块功能完全正确。
2计数器(notetabs)
计数器完成计数功能,183进制(最长的歌曲菊花台有183个字符)每个时钟沿加一。
用于选择rom模块中的地址。
(1)模块图像:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYNOTETABSIS
PORT(CLK:
INSTD_LOGIC;
COUNTER1:
inoutSTD_LOGIC_vector(7downto0));
ENDNOTETABS;
ARCHITECTUREaOFNOTeTABsIS
BEGIN
P1:
PROCESS(CLK,COUNTER1)
BEGIN
IFCOUNTER1=183THEN
COUNTER1<
="
00000000"
;
ELSIFCLK'
EVENTANDCLK='
THEN
=COUNTER1+1;
ENDIF;
ENDPROCESS;
ENDa;
由波形可看出,CLK为输入时钟信号,八位输出二进制信号在每个时钟上升沿加一(这一点由counter[7]~counter[0]可以看出,而counter1由于某某原因未能显示出,并不影响对该模块功能的判断)
经分析,该模块功能完全正确。
3选择模块(choice)
选择器完成选择歌曲的功能。
当a的信号为0001时将Q1的信号输出
为0011时将Q2的信号输出
为0010时将Q3的信号输出
为0110时将Q4的信号输出
ENTITYchoiceIS
PORT(a:
INSTD_LOGIC_vector(3downto0);
b:
outSTD_LOGIC_vector(3downto0);
INDEX:
OUTSTD_LOGIC_vector(4downto0);
Q1:
INSTD_LOGIC_vector(4downto0);
Q2:
Q3:
Q4:
INSTD_LOGIC_vector(4downto0));
ENDchoice;
ARCHITECTUREaOFchoiceIS
PROCESS(a,Q1,Q2,Q3,Q4)
CASEaIS
WHEN"
0001"
=>
b<
="
INDEX<
=Q1;
0011"
0010"
=Q2;
=Q3;
0110"
0100"
=Q4;
WHENOTHERS=>
null;
ENDCASE;
由波形可看出,当输入信号a为0010时输出信号b与q3信号相同(即播放q3的音乐),输出信号index与a相同(即音乐选取显示与音乐选取按键相同)
第二个波形图,当输入信号为0001时,同样可以看出这一点,因此该模块功能完全正确。
4数据翻译模块(tontaba):
将选择器所选择的歌曲rom里的地址的数据翻译成分频驱动器(数控分频器)分频所需的控制数据、3个led灯数据(高中低音)、以及译码器所需的数据。
libraryieee;
entitytonetabais
port(index:
instd_logic_vector(4downto0);
code:
outstd_logic_vector(3downto0);
high0:
outstd_logic_vector(2downto0);
tone:
outstd_logic_vector(11downto0));
end;
architectureoneoftonetabais
search:
process(index)
caseindexis
when"
00000"
=>
tone<
111111111111"
code<
0000"
high0<
000"
--0/4095
00001"
011100011111"
001"
--L1/1823
00010"
100000001111"
--L2/2063
00011"
100011110010"
--L3/2291
00100"
100101010101"
--L4/2390
00101"
101000010000"
0101"
--L5/2576
00110"
101010111000"
--L6/2745
00111"
101101001011"
0111"
--L7/2891
01000"
101110001111"
010"
--M1/2960
01001"
110000001001"
--M2/3082
01010"
110001111001"
--M3/3193
01011"
110010101100"
--M4/3244
01100"
110100001001"
--M5/3337
01101"
110101011100"
--M6/3420
01110"
110110100101"
--M7/3494
01111"
110111000111"
100"
--H1/3528
10000"
111000000101"
--H2/3589
10001"
111000111100"
--H3/3645
10010"
111001010110"
--H4/3670
10011"
111010000100"
--H5/3717
10100"
111010101101"
--H6/3758
10101"
111011010010"
--H7/3795
whenothers=>
null;
endcase;
endprocess;
由波形可看出,当输入信号index为00110时high0显示1,code显示6(即中音6),预置初值为101010111000,查询上文所列的表,可发现功能完全正确。
第二个波形图,输入信号00010,输出为中音2,再查预置初值,同样可发现完全正确。
因此该模块功能完全正确。
5.译码器模块(deled)
该模块在之前实验中做过,直接用即可,比较简单。
在此,只给出该模块的程序。
程序如下:
useieee.std_logic_arith.all;
entitydeledis
port(
num:
instd_logic_vector(3downto0);
led:
outstd_logic_vector(6downto0));
enddeled;
architecturefunofdeledis
--signalcount:
std_logic_vector(2downto0);
led<
1111110"
whennum="
else
"
0110000"
1101101"
1111001"
0110011"
1011011"
1011111"
1110000"
1111111"
1000"
1111011"
1001"
1110111"
1010"
0011111"
1011"
1001110"
1100"
0111101"
1101"
1001111"
1110"
1000111"
1111"
;
endfun;
6.数控分频器模块(speakera)
不多说其功能,直接看程序。
--音乐符数控分频电路模块
ENTITYSpeakeraIS
PORT(clk:
--音调频率信号12MHZ
Tone:
INSTD_LOGIC_VECTOR(10DOWNTO0);
--音乐符对应分频11位
SpkS:
OUTSTD_LOGIC);
--声音输出
END;
ARCHITECTUREoneOFSpeakeraIS
SIGNALPreCLK,FullSpkS:
STD_LOGIC;