VHDL数字电路与逻辑设计课程之音乐播放器Word文档格式.doc
《VHDL数字电路与逻辑设计课程之音乐播放器Word文档格式.doc》由会员分享,可在线阅读,更多相关《VHDL数字电路与逻辑设计课程之音乐播放器Word文档格式.doc(23页珍藏版)》请在冰点文库上搜索。
4.4资源利用率------------------------------------------------------------------------------22
4.5实验总结----------------------------------------------------------------------------------22
4.5.1实验遇到的故障及问题-----------------------------------------------------------------------------22
4.5.2实验感想总结----------------------------------------------------------------------------------------22
第5部分附录----------------------------------------------------------------------------23
5.1元器件清单-----------------------------------------------------------------------------23
5.2参考书目--------------------------------------------------------------------------------23
第1部分实验介绍
1.1实验题目
简易音乐播放器
1.2实验摘要
本系统是采用EDA技术设计的一个简易的5音符电子琴和音乐播放器,该系统基于计算机中时钟分频器的原理,采用自顶向下的设计方法来实现,它可以通过按键输入来控制音响。
系统实现是用硬件描述语言VHDL按模块化方式进行设计,然后进行编程、时序仿真、整合。
本系统功能比较齐全,有一定的使用价值
1.3任务及可实现功能
1.播放器内预存3首乐曲;
2.播放模式:
顺序播放、随机播放,或者自动弹奏模式,LED显示当前播放模式;
顺序播放:
按内部给定的顺序依次播放3首乐曲;
随机播放:
随机产生一个顺序播放3首乐曲;
自动弹奏:
可以手动弹奏想要的乐曲;
3.用数码管显示当前播放乐曲的顺序号;
4.设置开始/暂停键,乐曲播放过程中按该键则暂停播放,再按则继续播放;
5.设置Nexttone,Lasttone和Previous键,按Nexttone键可以听下一首,按Lasttone键可以听上一首,按Previous键回到本首重新开始;
6.用户可以自行设定播放顺序,设置完成后,播放器按该顺序依次
播放乐曲;
7.用户可以自行选择想听的歌曲,选择那首播放哪首
8.led等跟随音乐闪烁不同的颜色
9.点阵凭跟随音乐显示跳动的心
第2部分设计概要
2.1设计目的
(1)熟悉VHDL语言和Quartus2软件的使用
(2)理解状态机的工作原理和设计方法
(3)掌握利用EDA工具进行自顶向下的电子系统设计方法
2.2设计思路
根据VHDL自顶向下的设计思路,把简易乐曲播放器电路分为3个主要模块,即音乐播放music模块,音调发生tonet模块,数控分频speakera模块。
分好模块之后,编写每个模块的程序,分别生成项目符号,最后把生成的个项目符号用原理图的方式连接起来,然后编译、下载即可。
由图例表示如下:
输入(曲)输出(曲)
Speakera
ToneT
Music
2.3设计功能说明
1.音乐播放music模块
音乐播放模块的作用是产生发声控制输入信号。
当进行演奏时,有自此模块中的数作为发声控制输入,从而自动演奏音乐。
2.音调发生tone模块
音调发生模块的作用是产生音阶分频预置值。
当8位发生控制输入信号中的某一位为高电平时,则对应某一音阶的数值将输出,该数值即为该音阶的分频预置值,分频预置值控制数频分频模块进行分频,由此可得到每个音节对应的频率。
3.数控分频frequency模块
数控分频模块是对时基脉冲进行分频,得到与1,2,3,4,5,6,7七个音符相对应的频率。
4.灯光模块
控制led小灯,会跟着音乐打节拍。
5.点阵模块
控制点阵变化图形,跟随音乐,显示跳动的心脏
第3部分实验结果
3.1主程序流程图
否
是
上一首
本首
下一首
播放
是否播放/暂停
开始
顺序播放
随机播放
3.2主要功能模块代码
A.顶层函数mymusic
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_signed.all;
ENTITYmineIS
PORT
(CLK50MHZ:
INSTD_LOGIC;
--主频50M
reset:
hang,lie,hangnew:
outstd_logic_vector(7downto0);
--点阵
LED:
OUTSTD_LOGIC_VECTOR(6DOWNTO0);
--彩灯功能
SOC:
INSTD_LOGIC;
--暂停或播放
SHOW:
OUTSTD_LOGIC;
--播放模式显示
NEXTONE:
--下一首
LASTONE:
--上一首
PREVIOUS:
--本首重来
SPKOUT:
--音频输出
MODE:
--播放模式
SEG:
OUTSTD_LOGIC_VECTOR(6DOWNTO0);
--歌曲序号显示
CAT:
OUTSTD_LOGIC_VECTOR(5DOWNTO0);
--第1个数码管显示歌曲序号
STOP:
INSTD_LOGIC
);
END;
ARCHITECTUREoneOFmineIS
COMPONENTNoteTabs
PORT(clk:
--4Hz
ToneIndex:
OUTINTEGERRANGE0TO15;
--音调
SEG:
--7段数码管输出
RANDOM:
SOC:
--播放或暂停STOPORCONTINUE
NEXTONE:
--下一首
LASTONE:
--上一首
PREVIOUS:
INSTD_LOGIC;
--本首重来
MODE:
--播放模式
SHOW:
OUTSTD_LOGIC;
--播放模式显示
CAT:
--第1个数码管显示歌曲序号
reset3:
instd_logic;
hang3:
hangnew3:
lie3:
outstd_logic_vector(7downto0)
);
ENDCOMPONENT;
COMPONENTToneT
PORT(Index:
ININTEGERRANGE0TO15;
--音调
LED:
Tone:
OUTINTEGERRANGE0TO16#7FF#--――分频系数
);
COMPONENTSpeakera
PORT
(clk:
--1Mhz
Tone:
ININTEGERRANGE0TO16#7FF#;
--分频系数
SpkS:
OUTSTD_LOGIC);
--给蜂鸣器的频率信号
ENDCOMPONENT;
COMPONENTdivide
port(
clk:
clk_out:
ENDCOMPONENT;
SIGNALTone:
INTEGERRANGE0TO16#7FF#;
SIGNALToneIndex:
INTEGERRANGE0TO15;
SIGNALT:
STD_LOGIC;
--分频信号
SIGNALCLK1MHZ:
--signalclk_tmp1:
std_logic;
signalstate:
integerrange0to2;
signalh3,hnew3,l3:
std_logic_vector(7downto0);
CONSTANTLENGTH:
POSITIVE:
=8;
CONSTANTTAP1:
CONSTANTTAP2:
=4;
SIGNALPRBS:
SIGNALPRREG:
STD_LOGIC_VECTOR(LENGTHDOWNTO0);
BEGIN
PROCESS(CLK50MHZ)--T分50M
VARIABLEb:
INTEGERRANGE0TO24;
BEGIN
IF(CLK50MHZ'
EVENTANDCLK50MHZ='
1'
)THEN
IF(b=24)THEN
b:
=0;
CLK1MHZ<
=NOTCLK1MHZ;
ELSE
b:
=b+1;
ENDIF;
ENDIF;
ENDPROCESS;
PROCESS(CLK1MHZ)--T分1M频为4Hz
VARIABLEC:
INTEGERRANGE0TO124999;
IF(CLK1MHZ'
EVENTANDCLK1MHZ='
IF(C=124999)THEN
C:
T<
=NOTT;
=C+1;
process(T,STOP)--产生一个伪随机信号
begin
ifSTOP='
then
prreg<
=(others=>
'
0'
);
prreg(0)<
='
;
elsifT'
eventandT='
=(prreg((length-1)downto0)&
(prreg(tap1)xorprreg(tap2)));
endif;
endprocess;
prbs<
=prreg(length);
--prbs随机为0或1
--fp:
dividePORTMAP(clk=>
CLK50MHZ,clk_out=>
clk_tmp1);
u1:
NoteTabsPORTMAP(clk=>
T,MODE=>
MODE,SHOW=>
SHOW,ToneIndex=>
ToneIndex,
RANDOM=>
PRBS,SEG=>
SEG,SOC=>
SOC,NEXTONE=>
NEXTONE,LASTONE=>
LASTONE,PREVIOUS=>
PREVIOUS,CAT=>
CAT,hang3=>
h3,hangnew3=>
hnew3,lie3=>
l3,reset3=>
reset);
u2:
ToneTPORTMAP(Index=>
ToneIndex,Tone=>
Tone,LED=>
LED);
u3:
SpeakeraPORTMAP(clk=>
CLK1MHZ,Tone=>
Tone,SpkS=>
SPKOUT);
B音乐播放模块notetabs
ENTITYNoteTabsIS
PORT(clk:
DUO:
--1
clk3,reset3:
ARCHITECTUREoneOFNoteTabsIS
SIGNALCounter:
INTEGERRANGE0TO152;
signalchushi:
std_logic_vector(14downto0):
="
000000000000000"
signalgaowei:
std_logic_vector(1downto0);
signaldiwei:
std_logic_vector(2downto0);
CNT8:
PROCESS(clk,SOC,MODE,RANDOM,NEXTONE,LASTONE,PREVIOUS)
BEGIN
IF(clk'
EVENTANDclk='
)THEN
IF(NEXTONE='
ANDLASTONE='
ANDPREVIOUS='
ANDMODE='
ANDSOC='
)THEN--顺序播放模式下
SHOW<
--灯灭
IFCounter=152THENCounter<
ELSECounter<
=Counter+1;
ENDIF;
ELSIF(NEXTONE='
ANDLASTONE='
)THEN--随机播放模式下
--灯亮
IFCounter=47THEN--每首歌完后,如果随机信号为0则播放下一首歌
IFRANDOM='
THENCounter<
=48;
--如果为1,则播放前一首歌。
这一切都可由改变状态
ELSIFRANDOM='
THENCounter<
=97;
--计数器Counter来实现
ENDIF;