#基于EDA音乐播放器的设计.docx

上传人:b****3 文档编号:27094674 上传时间:2023-06-27 格式:DOCX 页数:21 大小:191.23KB
下载 相关 举报
#基于EDA音乐播放器的设计.docx_第1页
第1页 / 共21页
#基于EDA音乐播放器的设计.docx_第2页
第2页 / 共21页
#基于EDA音乐播放器的设计.docx_第3页
第3页 / 共21页
#基于EDA音乐播放器的设计.docx_第4页
第4页 / 共21页
#基于EDA音乐播放器的设计.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

#基于EDA音乐播放器的设计.docx

《#基于EDA音乐播放器的设计.docx》由会员分享,可在线阅读,更多相关《#基于EDA音乐播放器的设计.docx(21页珍藏版)》请在冰豆网上搜索。

#基于EDA音乐播放器的设计.docx

#基于EDA音乐播放器的设计

长沙学院

课程设计说明书

题目音乐播放器的设计

系(部)电子与通信工程

专业(班级)电气工程及其自动化(一班)

姓名

学号

指导教师

起止日期2010-11-29至2010-12-10

EDA技术课程设计任务书

系(部):

电子与通信工程系专业:

电气工程及其自动化指导教师:

课题名称

音乐播放器的设计

设计内容及要求

在SOPC开发平台上实现一个音频信号发生器,编写3段音乐,利用开发平台的蜂鸣器来播放几段音乐。

可进行自动循环播放和手动播放两个模式的选择。

如果为手动播放,则通过拨动拨码开关第1、2位选择。

播放音乐时,要求将该音乐的序号(分别为A1、A2,A3)以及该音乐播放剩余的时间(分、秒)显示在数码管上。

当某首音乐开始播放时,音乐序号闪烁显示3秒钟。

系统提供50MHZ频率的时钟源。

完成该系统的硬件和软件的设计,并制作出实物装置,调试好后并能实际运用(指导教师提供制作所需的器件),最后就课程设计本身提交一篇课程设计说明书。

设计工作量

1、VHDL语言程序设计;

2、波形仿真;

3、在实验装置上进行硬件测试,并进行演示;

4、提交一份完整的课程设计说明书,包括设计原理、程序设计、程序分析、仿真分析、硬件测试、调试过程,参考文献、设计总结等。

进度安排

起止日期(或时间量)

设计内容(或预期目标)

备注

第1天

课题介绍,答疑,收集材料

第2天

设计方案论证

第3天

进一步讨论方案,对设计方案进行必要的修正,方案确定后开始进行VHDL语言程序设计

第4天

设计VHDL语言程序

第5~9天

在实验装置上进行硬件测试,对VHDL语言程序进行必要的修正,并进行演示

第10天

编写设计说明书

教研室

意见

年月日

系(部)主管领导意见

年月日

长沙学院课程设计鉴定表

姓名

学号

专业

电气工程及其自动化

班级

设计题目

音乐播放器的设计

指导教师

指导教师意见:

评定等级:

教师签名:

日期:

答辩小组意见:

评定等级:

     答辩小组长签名:

     日期:

    

教研室意见:

教研室主任签名:

日期:

 

系(部)意见:

系主任签名:

        日期:

     

说明

课程设计成绩分“优秀”、“良好”、“及格”、“不及格”四类;

摘要:

在SOPC开发平台上实现一个音频信号发生器,编写3段音乐,利用开发平台的蜂鸣器来播放几段音乐。

可进行自动循环播放和手动播放两个模式的选择。

如果为手动播放,则通过拨动拨码开关第1、2位选择。

播放音乐时,要求将该音乐的序号(分别为A1、A2,A3)以及该音乐播放剩余的时间(分、秒)显示在数码管上。

当某首音乐开始播放时,音乐序号闪烁显示3秒钟。

关键字:

SOPC、音频信号、音乐、蜂鸣器、自动循环、手动播放、剩余时间(分钟、秒钟)显示、音乐序号(A1、A2、A3)显示。

设计原理:

首先采用分块设计法,将设计分为分频模块、时间动态扫描显示模块、音乐播放模块、顶层模块。

其中音乐播放模块又可分为音频模块、音乐代码模块,预置数模块

利用计数的方式将50MHZ的频率分为12MHz、100Hz、8Hz、1Hz。

音乐播放模块需要完成以下设计:

①预置乐曲,本次设计选取了《梁祝》的一段作预置,在作预置时,需要将乐曲音符转换成相应的代码,通过计算逐一将音符转换成代码,通过EDA开发平台quartusⅡ进行乐曲定制;

②为了提供乐曲发音所需要的发音频率,编写数控分频器程序,对单一输入高频,进行预置数分频,生成每个音符发音的相应频率;

③为了给分频提供预置数,需要计算分频预置数;

对每部分结构单元逐一进行编译,生成相应的元器件符号,并对独立结构单元功能进行仿真。

音调的控制

频率的高低决定了音调的高低。

综合考虑各因素,本次设计中选取12MHZ作为CLK的分频计数器的输入分频信号。

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

表1 简谱中的音名与频率的关系

音名

频率/Hz

音名

频率/Hz

音名

频率/Hz

低音1

261.6

中音1

523.3

高音1

1045.5

低音2

293.7

中音2

587.3

高音2

1174.7

低音3

329.6

中音3

659.3

高音3

1318.5

低音4

349.2

中音4

698.5

高音4

1396.9

低音5

392

中音5

784

高音5

1568

低音6

440

中音6

880

高音6

1760

低音7

493.9

中音7

987.8

高音7

1975.5

音长的控制

这次设计中所演奏的乐曲的最短的音符为四分音符,如果将全音符的持续时间设为1s的话,那么一拍所应该持续的时间为0.25秒,则只需要再提供一个4Hz的时钟频率即可产生四分音符的时长。

系统工作时就按4Hz的频率依次读取简谱,当系统读到某个音符的简谱时就对应发这个音符的音调,持续时间为0.25秒.如果在曲谱文件中某个音符为三拍音长,只要将该音符连续书写三遍,系统读乐曲文件的时候就会连续读到三次,也就会发三个0.25秒的音长,这时我们听上去就会持续了三拍的时间,这样就可以控制音乐的音长了

程序:

音乐播放器顶层模块

libraryieee;

useieee.std_logic_1164.all;

entitysongeris

port(clk50mhz,c:

instd_logic;

led7s:

bufferstd_logic_vector(6downto0);

led_selout:

outstd_logic_vector(7downto0);

spkout:

outstd_logic);

end;

architectureoneofsongeris

componentnotetabs

port(clk:

instd_logic;

f1s,f8,f12,fs:

outstd_logic);

endcomponent;

componentnotetabs

port(clk:

instd_logic;

toneindex:

outstd_logic_vector(3downto0));

endcomponent;

componenttonetaba

port(index:

instd_logic_vector(3downto0);

tone:

outstd_logic_vector(10downto0));

endcomponent;

componentspeakera

port(clk:

instd_logic;

tone:

instd_logic_vector(10downto0);

spks:

outstd_logic);

endcomponent;

componentdaojishi

port(clk1,clk2,c:

instd_logic;

led7s:

bufferstd_logic_vector(6downto0);

led_selout:

outstd_logic_vector(7downto0));

endcomponent;

signaltone:

std_logic_vector(10downto0);

signaltoneindex:

std_logic_vector(3downto0);

signalff1,ff8,ff12,ffs:

std_logic_vector;

begin

u1:

fpportmap(clk=>clk50mhz,f1s=>ff1,f8=>ff8,f12=>ff12,fs=>ffs);

u2:

notetabsportmap(clk=>ff8,toneindex=>toneindex);

u3:

tonetabaportmap(index=>toneindex,tone=>tone);

u4:

speakeraportmap(clk=>ff12,tone=>tone,spks=>spkout);

u5:

daojishiportmap(clk1=>ff1,clk2=>ffs,c=>c,led7s=>led7s,led_selout=>led_selout);

end;

分频模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityfpis

port(clk:

instd_logic;

f1s,f8,f12,fs:

outstd_logic);

end;

architecturebhvoffpis

signala,c,f:

std_logic;

signala2,c2,f2:

std_logic;

begin

process(clk)

variablecnt24:

std_logic_vector(25downto0);

variablecnt8:

std_logic_vector(7downto0);

begin

ifclk'eventandclk='1'then

ifcnt24<"01011111010111100001000000"then

cnt24:

=cnt24+1;

f1s<='0';

elsif

cnt24<"10111110101111000010000000"then

cnt24:

=cnt24+1;

f1s<='1';

else

cnt24:

="00000000000000000000000000";

endif;

ifcnt8<"1100100"then

cnt8:

=cnt8+1;

fs<='0';

elsif

cnt8<"11001000"then

cnt8:

=cnt8+1;

fs<='1';

else

cnt8:

="00000000";

endif;

endif;

endprocess;

process(clk,a)

variablecnt:

std_logic_vector(2downto0);

begin

ifclk'eventandclk='1'then

ifcnt="111"then

cnt:

="011";

a<='1';

else

cnt:

=cnt+1;a<='0';

endif;

endif;

ifa'eventanda='1'then

c<=notc;

ifc='1'thenf<='1';

elsef<='0';

endif;

endif;

f12<=f;

endprocess;

process(clk,a2)

variablecn:

std_logic_vector(22downto0);

begin

ifclk'eventandclk='1'then

ifcn="10111110101111000010000"then

cn:

="01011111010111100001000";

a2<='1';

else

cn:

=cn+1;a<='0';

endif;

endif;

ifa2'eventanda2='1'then

c2<=notc2;

ifc2='1'thenf2<='1';

elsef2<='0';

endif;

endif;

f8<=f;

endprocess;

end;

fp模块将50MHz的频率分为所需要的频率。

预置数模块

libraryieee;

useieee.std_logic_1164.all;

entitytonetabais

port(index:

instd_logic_vector(3downto0);

tone:

outstd_logic_vector(10downto0));

end;

architectureoneoftonetabais

signalcode:

outstd_logic_vector(3downto0);

signalhigh:

outstd_logic;

begin

search:

process(index)

begin

caseindexis

when"0000"=>tone<="11111111111";code<="0000";high<='0';

when"0001"=>tone<="01100000101";code<="0001";high<='0';

when"0010"=>tone<="01110010000";code<="0010";high<='0';

when"0011"=>tone<="10000001100";code<="0011";high<='0';

when"0101"=>tone<="10010101101";code<="0101";high<='0';

when"0110"=>tone<="10100001010";code<="0110";high<='0';

when"0111"=>tone<="10101011100";code<="0111";high<='0';

when"1000"=>tone<="10110000010";code<="0001";high<='1';

when"1001"=>tone<="10111001000";code<="0010";high<='1';

when"1010"=>tone<="11000000110";code<="0011";high<='1';

when"1100"=>tone<="11001010110";code<="0101";high<='1';

when"1101"=>tone<="11010000100";code<="0110";high<='1';

when"1111"=>tone<="11011000000";code<="0001";high<='1';

whenothers=>null;

endcase;

endprocess;

end;

模块tonetaba的功能首先是为speakera提供决定音符发音的分频预置数,而此数在speakera输入口停留时间即为此音符的节拍值。

模块tonetaba是乐曲简谱码对应的分频预置数查表电路,其中设置了《梁祝》乐曲全部音符所对应的分频预置数,共13个,每一个音符的停留时间由音乐节拍和音调发生器模块notetabs的clk输入频率决定,在此时为4HZ。

每一个计数值停留时间为0.25秒,恰为当全音符为1秒时,四四拍的4分音符持续时间。

这13个值的输出由对应于tonetaba的4位输入值index[3..0]确定,而index[3..0]最多有16种选择。

输向tonetaba中index[3..0]的值toneindex[3..0]的输出值与持续的时间由模块notetabs决定。

音频模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entityspeakerais

port(clk:

instd_logic;

tone:

instd_logic_vector(10downto0);

spks:

outstd_logic);

end;

architectureoneofspeakerais

signalpreclk,fullspks:

std_logic;

begin

divideclk:

process(clk)

variablecount4:

std_logic_vector(3downto0);

begin

preclk<='0';

ifcount4>11thenpreclk<='1';

count4:

="0000";

elsifclk'eventandclk='1'thencount4:

=count4+1;

endif;

endprocess;

genspks:

process(preclk,tone)

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)

variablecount2:

std_logic;

begin

iffullspks'eventandfullspks='1'then

count2:

=notcount2;

ifcount2='1'thenspks<='1';

elsespks<='0';

endif;

endif;

endprocess;

end;

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

为了得到合适的发音频率,在进行预置计数分频之前需要将本文选择的12MHz初始频率信号进行十六分频,采用四位加法计数方式分频,当输入一个脉冲信号,计数器做一次加法计数,此时输入信号脉宽展宽一倍(即进行一次二分频),十六分频后得到0.75MHz输入频率。

由于数控分频器输出的信号是脉宽很窄的信号,为了有利于驱动扬声器发音,需要加一个D触发器以均衡占空比,但这样一来,此时频率变为原来的二分之一即0.375MHZ。

可预置计数分频器就是将0.375MHZ按照各音符发音所需要的频率值进行预置数分频。

这里计数器设为11位(tone[10..0]),模为2047。

若取音符3发音频率为659Hz,需要将0.375MHz进行约569次分频才能得到此频率。

预置数即可用公式“模-分频系数=预置数tone[10..0]”算出,此时为“2047-569=1478(换成11位二进制计数为10111000110)”。

音乐代码模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entitynotetabsis

port(clk:

instd_logic;

toneindex:

outstd_logic_vector(3downto0));

end;

architectureoneofnotetabsis

componentmusic

port(address:

instd_logic_vector(7downto0);

clock:

instd_logic;

q:

outstd_logic_vector(3downto0));

endcomponent;

signalcounter:

std_logic_vector(7downto0);

begin

cnt8:

process(clk,counter)

begin

ifcounter=138thencounter<="00000000";

elsifclk'eventandclk='1'thencounter<=counter+1;endif;

endprocess;

u1:

musicportmap(address=>counter,q=>toneindex,clock=>clk);

end;

notetabs中设置了一个8位二进制计数器,作为音符数据的地址发生器。

随着notetabs中的计数器按照4Hz的时钟速率作加法计数时,每读一个数据,音符持续时间为0.25秒,如音符数据中的中音3,为一拍,持续时间1秒,所以,音符数据ROM中需要重复写四次地址0A,随着4Hz时钟速率读取地址递增,音符数据ROM中的音符数据将通过模块notetabs中toneindex[3..0]端口输向tonetaba模块。

《梁祝》音符数据ROM

以下排列方法是为了节省空间,实际文件每一组占一行。

width=4;

depth=256;

address_radix=dec;

data_radix=dec;

contentbegin

00:

3;01:

3;02:

3;04:

5:

05:

5;06:

5;07:

6;08:

8;09:

8;

10:

8;11:

9;12:

6;13:

8;14:

5;15:

5;16:

12;17:

12;18:

12;19:

15;

20:

13;21:

12;22:

10;23:

12;24:

9;25:

9;26:

9;27:

9;28:

9;29:

9;

30:

9;31:

0;32:

9;33:

9;34:

9;35:

10;36:

7;37:

7;38:

6;39:

6;

40:

5;41:

5;42:

5;43:

6;44:

8;45:

8;46:

9;47:

9;48:

3;49:

3;

50:

8;51:

8;52:

6;53:

5;54:

6;55:

8;56:

5;57:

5;58:

5;59:

5;

60:

5;61:

5;62:

5;63:

5;64:

10;65:

10;66:

10;67:

12;68:

7;69:

7;

70:

9;71:

9;72:

6;73:

8;74:

5;75:

5;76:

5;77:

5;78:

5;79:

5;

80:

3;81:

5;82:

3;83:

3;84:

5;85:

6;86:

7;87:

9;88:

6;89:

6;

90:

6;91:

6;92:

6;93:

6:

94:

5;95:

6;96:

8;97:

8;98:

8;99:

9;

100:

12;101:

12;103:

10;104:

9;105:

9;106:

10;107:

9;108:

8;109:

8;

110:

6;111:

5;112:

3;113:

3;114:

3;115:

9;116:

8;117:

8;118:

8;119:

8;

120:

6;121:

8;122:

6;123:

5;124:

3;125:

5;126:

6;127:

8;128:

5;129:

5;

130:

5;131:

5;132:

5;133:

5;134:

5;135:

5;136:

0;137:

0;138:

0;

end;

时间动态扫描模块

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_unsigned.all;

entitydaojishiis

port(clk1,clk2,c:

instd_logic;

led7s:

bufferstd_logic_vector(6downto0);

led_selout:

out

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

当前位置:首页 > 法律文书 > 辩护词

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

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