当前位置:文档之家› 基于EDA音乐播放器的设计

基于EDA音乐播放器的设计

长沙学院课程设计说明书题目音乐播放器的设计系(部) 电子与通信工程专业(班级) 电气工程及其自动化(一班)姓名学号指导教师起止日期 2010-11-29至2010-12-10EDA技术课程设计任务书系(部):电子与通信工程系专业:电气工程及其自动化指导教师:长沙学院课程设计鉴定表目录摘要 (4)设计原理 (5)程序: (6)实验现象: (14)引脚分配: (14)仿真波形: (15)心得体会: (16)参考文献: (16)摘要:在SOPC开发平台上实现一个音频信号发生器,编写3段音乐,利用开发平台的蜂鸣器来播放几段音乐。

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

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

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

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

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

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

其中音乐播放模块又可分为音频模块、音乐代码模块,预置数模块利用计数的方式将50MHZ的频率分为12MHz、100Hz、8Hz、1Hz。

音乐播放模块需要完成以下设计:①预置乐曲,本次设计选取了《梁祝》的一段作预置,在作预置时,需要将乐曲音符转换成相应的代码,通过计算逐一将音符转换成代码,通过EDA开发平台quartus Ⅱ进行乐曲定制;②为了提供乐曲发音所需要的发音频率,编写数控分频器程序,对单一输入高频,进行预置数分频,生成每个音符发音的相应频率;③为了给分频提供预置数,需要计算分频预置数;对每部分结构单元逐一进行编译,生成相应的元器件符号,并对独立结构单元功能进行仿真。

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

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

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

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

系统工作时就按4Hz的频率依次读取简谱,当系统读到某个音符的简谱时就对应发这个音符的音调,持续时间为0.25秒.如果在曲谱文件中某个音符为三拍音长,只要将该音符连续书写三遍,系统读乐曲文件的时候就会连续读到三次,也就会发三个0.25秒的音长,这时我们听上去就会持续了三拍的时间,这样就可以控制音乐的音长了程序:音乐播放器顶层模块library ieee;use ieee.std_logic_1164.all;entity songer isport(clk50mhz,c:in std_logic;led7s:buffer std_logic_vector(6 downto 0);led_selout:out std_logic_vector(7 downto 0);spkout:out std_logic);end;architecture one of songer iscomponent notetabsport(clk:in std_logic;f1s,f8,f12,fs:out std_logic);end component;component notetabsport(clk:in std_logic;toneindex:out std_logic_vector(3 downto 0));end component;component tonetabaport(index:in std_logic_vector(3 downto 0);tone:out std_logic_vector(10 downto 0));end component;component speakeraport(clk:in std_logic;tone:in std_logic_vector(10 downto 0);spks:out std_logic);end component;component daojishiport(clk1,clk2,c:in std_logic;led7s:buffer std_logic_vector(6 downto 0);led_selout:out std_logic_vector(7 downto 0));end component;signal tone:std_logic_vector(10 downto 0);signal toneindex:std_logic_vector(3 downto 0);signal ff1,ff8,ff12,ffs:std_logic_vector;beginu1:fp port map(clk=>clk50mhz,f1s=>ff1,f8=>ff8,f12=>ff12,fs=>ffs);u2:notetabs port map(clk=>ff8,toneindex=>toneindex);u3:tonetaba port map(index=>toneindex,tone=>tone);u4:speakera port map(clk=>ff12,tone=>tone,spks=>spkout);u5:daojishi port map(clk1=>ff1,clk2=>ffs,c=>c,led7s=>led7s,led_selout=>led_selout); end;分频模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity fp isport(clk:in std_logic;f1s,f8,f12,fs:out std_logic);end;architecture bhv of fp issignal a,c,f:std_logic;signal a2,c2,f2:std_logic;beginprocess(clk)variable cnt24:std_logic_vector(25 downto 0);variable cnt8:std_logic_vector(7 downto 0);beginif clk'event and clk='1' thenif cnt24<"01011111010111100001000000" thencnt24:=cnt24+1;f1s<='0';elsifcnt24<"10111110101111000010000000" thencnt24:=cnt24+1;f1s<='1';elsecnt24:="00000000000000000000000000";end if;if cnt8<"1100100" thencnt8:=cnt8+1;fs<='0';elsifcnt8<"11001000" thencnt8:=cnt8+1;fs<='1';elsecnt8:="00000000";end if;end if;end process;process(clk,a)variable cnt:std_logic_vector(2 downto 0);beginif clk'event and clk='1'thenif cnt="111"thencnt:="011";a<='1';elsecnt:=cnt+1;a<='0';end if;end if;if a'event and a='1'thenc<=not c;if c='1'then f<='1';else f<='0';end if;end if;f12<=f;end process;process(clk,a2)variable cn:std_logic_vector(22 downto 0);beginif clk'event and clk='1'thenif cn="10111110101111000010000"thencn:="01011111010111100001000";a2<='1';elsecn:=cn+1;a<='0';end if;end if;if a2'event and a2='1'thenc2<=not c2;if c2='1'then f2<='1';else f2<='0';end if;end if;f8<=f;end process;end;fp 模块将50MHz的频率分为所需要的频率。

预置数模块library ieee;use ieee.std_logic_1164.all;entity tonetaba isport(index:in std_logic_vector(3 downto 0);tone:out std_logic_vector(10 downto 0));end;architecture one of tonetaba issignal code:out std_logic_vector(3 downto 0);signal high:out std_logic;beginsearch:process(index)begincase index iswhen"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';when others=>null;end case;end process;end;模块tonetaba的功能首先是为speakera提供决定音符发音的分频预置数,而此数在speakera输入口停留时间即为此音符的节拍值。

相关主题