|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区
您需要 登录 才可以下载或查看,没有账号?立即注册
×
第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模块。分好模块之后,编写每个模块的程序,分别生成项目符号,最后把生成的个项目符号用原理图的方式连接起来,然后编译、下载即可。
由图例表示如下:
输入(曲) 输出(曲)
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps1.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps2.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps3.png
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps4.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps5.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps6.pngfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps7.png
2.3 设计功能说明
1.音乐播放music模块
音乐播放模块的作用是产生发声控制输入信号。当进行演奏时,有自此模块中的数作为发声控制输入,从而自动演奏音乐。
2.音调发生tone模块
音调发生模块的作用是产生音阶分频预置值。当8位发生控制输入信号中的某一位为高电平时,则对应某一音阶的数值将输出,该数值即为该音阶的分频预置值,分频预置值控制数频分频模块进行分频,由此可得到每个音节对应的频率。
3.数控分频frequency模块
数控分频模块是对时基脉冲进行分频,得到与1,2,3,4,5,6,7七个音符相对应的频率。
4.灯光模块
控制led小灯,会跟着音乐打节拍。
5.点阵模块
控制点阵变化图形,跟随音乐,显示跳动的心脏第3部分 实验结果
3.1主程序流程图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps8.png[td=1,1,0.133333]file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps9.png
3.2主要功能模块代码
A.顶层函数mymusic
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
ENTITY mine IS
PORT
(CLK50MHZ :IN STD_LOGIC; --主频50M
reset:IN STD_LOGIC;
hang,lie,hangnewut std_logic_vector(7 downto 0); --点阵
LED: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --彩灯功能
SOC : IN STD_LOGIC; --暂停或播放
SHOW : OUT STD_LOGIC; --播放模式显示
NEXTONE : IN STD_LOGIC; --下一首
LASTONE : IN STD_LOGIC; --上一首
PREVIOUS : IN STD_LOGIC; --本首重来
SPKOUT: OUT STD_LOGIC; --音频输出
MODE : IN STD_LOGIC; --播放模式
SEG:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --歌曲序号显示
CAT:OUT STD_LOGIC_VECTOR(5 DOWNTO 0); --第1个数码管显示歌曲序号
STOP: IN STD_LOGIC
);
END;
ARCHITECTURE one OF mine IS
COMPONENT NoteTabs
PORT ( clk :IN STD_LOGIC; --4Hz
ToneIndex : OUT INTEGER RANGE 0 TO 15; --音调
SEG:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --7段数码管输出
RANDOM: IN STD_LOGIC;
SOC : IN STD_LOGIC; --播放或暂停STOP OR CONTINUE
NEXTONE: IN STD_LOGIC; --下一首
LASTONE : IN STD_LOGIC; --上一首
PREVIOUS : IN STD_LOGIC ; --本首重来
MODE : IN STD_LOGIC; --播放模式
SHOW :OUT STD_LOGIC; --播放模式显示
CAT:OUT STD_LOGIC_VECTOR(5 DOWNTO 0); --第1个数码管显示歌曲序号
reset3:in std_logic;
hang3ut std_logic_vector(7 downto 0);
hangnew3ut std_logic_vector(7 downto 0);
lie3ut std_logic_vector(7 downto 0)
);
END COMPONENT;
COMPONENT ToneT
PORT ( Index: IN INTEGER RANGE 0 TO 15; --音调
LED : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
Tone : OUT INTEGER RANGE 0 TO 16#7FF#--――分频系数
);
END COMPONENT;
COMPONENT Speakera
PORT
(clk:IN STD_LOGIC; --1Mhz
Tone:IN INTEGER RANGE 0 TO 16#7FF#; --分频系数
SpkS:OUT STD_LOGIC); --给蜂鸣器的频率信号
END COMPONENT;
COMPONENT divide
port(
clk:IN STD_LOGIC;
clk_out:OUT STD_LOGIC);
END COMPONENT;
SIGNAL Tone : INTEGER RANGE 0 TO 16#7FF#;
SIGNAL ToneIndex :INTEGER RANGE 0 TO 15;
SIGNAL T:STD_LOGIC; --分频信号
SIGNAL CLK1MHZ:STD_LOGIC;
--signal clk_tmp1:std_logic;
signal state:integer range 0 to 2;
signal h3,hnew3,l3:std_logic_vector(7 downto 0);
CONSTANT LENGTHOSITIVE:=8;
CONSTANT TAP1OSITIVE:=8;
CONSTANT TAP2OSITIVE:=4;
SIGNAL PRBS:STD_LOGIC;
SIGNAL PRREG:STD_LOGIC_VECTOR(LENGTH DOWNTO 0);
BEGIN
PROCESS(CLK50MHZ) --T分50M
VARIABLE b:INTEGER RANGE 0 TO 24;
BEGIN
IF(CLK50MHZ'EVENT AND CLK50MHZ='1')THEN
IF(b=24)THEN
b:=0;
CLK1MHZ<=NOT CLK1MHZ;
ELSE
b:=b+1;
END IF;
END IF;
END PROCESS;
PROCESS(CLK1MHZ) --T分1M频为4Hz
VARIABLE C:INTEGER RANGE 0 TO 124999;
BEGIN
IF(CLK1MHZ'EVENT AND CLK1MHZ='1')THEN
IF(C=124999)THEN
C:=0;
T<=NOT T;
ELSE
C:=C+1;
END IF;
END IF;
END PROCESS;
process(T,STOP) --产生一个伪随机信号
begin
if STOP='1' then
prreg<=(others=>'0');
prreg(0)<='1';
elsif T'event and T='1' then
prreg<=(prreg((length-1)downto 0)&
(prreg(tap1)xor prreg(tap2)));
end if;
end process;
prbs<=prreg(length); --prbs随机为0或1
--fp: divide PORT MAP(clk=>CLK50MHZ,clk_out=>clk_tmp1);
u1: NoteTabs PORT MAP(clk=>T,MODE=>MODE,SHOW=>SHOW, ToneIndex => ToneIndex,
RANDOM=>RBS,SEG=>SEG,SOC=>SOC,NEXTONE=>NEXTONE,LASTONE=>LASTONE,PREVIOUS=>REVIOUS,CAT=>CAT,hang3=>h3,hangnew3=>hnew3,lie3=>l3,reset3=>reset);
u2: ToneT PORT MAP(Index=>ToneIndex, Tone=>Tone,LED=>LED);
u3: Speakera PORT MAP(clk=>CLK1MHZ,Tone=>Tone ,SpkS=>SPKOUT);
END;
B 音乐播放模块notetabs
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
ENTITY NoteTabs IS
PORT ( clk :IN STD_LOGIC; --4Hz
ToneIndex : OUT INTEGER RANGE 0 TO 15; --音调
SEG:OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --7段数码管输出
RANDOM: IN STD_LOGIC;
SOC : IN STD_LOGIC; --播放或暂停STOP OR CONTINUE
NEXTONE: IN STD_LOGIC; --下一首
LASTONE : IN STD_LOGIC; --上一首
PREVIOUS : IN STD_LOGIC ; --本首重来
DUO:IN STD_LOGIC; --1
MODE : IN STD_LOGIC; --播放模式
SHOW :OUT STD_LOGIC; --播放模式显示
CAT:OUT STD_LOGIC_VECTOR(5 DOWNTO 0);
clk3,reset3:in std_logic;
hang3ut std_logic_vector(7 downto 0);
hangnew3ut std_logic_vector(7 downto 0);
lie3ut std_logic_vector(7 downto 0)
);
END;
ARCHITECTURE one OF NoteTabs IS
SIGNAL Counter : INTEGER RANGE 0 TO 152;
signal chushi:std_logic_vector(14 downto 0):="000000000000000";
signal gaowei:std_logic_vector(1 downto 0);
signal diwei:std_logic_vector(2 downto 0);
BEGIN
CNT8: PROCESS(clk,SOC,MODE, RANDOM,NEXTONE,LASTONE,PREVIOUS)
BEGIN
IF(clk'EVENT AND clk='1') THEN
IF( NEXTONE='0' AND LASTONE='0' AND PREVIOUS='0' AND MODE='0' AND SOC='0' ) THEN --顺序播放模式下
SHOW<='0'; --灯灭
IF Counter=152 THEN Counter <=0;
ELSE Counter<=Counter+1;
END IF;
ELSIF (NEXTONE='0' AND LASTONE='0' AND PREVIOUS='0' AND MODE='1' AND SOC='0' )THEN --随机播放模式下
SHOW<='1'; --灯亮
IF Counter=47 THEN --每首歌完后,如果随机信号为0则播放下一首歌
IF RANDOM='0' THEN Counter<=48; --如果为1,则播放前一首歌。这一切都可由改变状态
ELSIF RANDOM='1' THEN Counter<=97; --计数器Counter来实现
END IF;
ELSIF Counter=96 THEN
IF RANDOM='0' THEN Counter<=97;
ELSIF RANDOM='1' THEN Counter<=00;
END IF;
ELSIF Counter=152 THEN
IF RANDOM='0' THEN Counter<=00;
ELSIF RANDOM='1' THEN Counter<=48;
END IF;
ELSE Counter<=Counter+1;
END IF;
ELSIF SOC='1' THEN --如果暂停了,计数器暂停计数
Counter<=Counter;
ELSIF (NEXTONE='1' AND LASTONE='0' AND PREVIOUS='0') THEN --选择下一首,将计数器改为下首歌曲开始的一个数
IF(Counter<=47) THEN Counter<=48;
ELSIF(Counter>=48 and Counter<=96) THEN Counter<=97;
ELSIF(Counter>=97) THEN Counter<=00;
END IF;
ELSIF(NEXTONE='0' AND LASTONE='1' AND PREVIOUS='0') THEN --选择上一首,将计数器直改为上首歌曲开始的一个数
IF(Counter<=47) THEN Counter<=97;
ELSIF(Counter>=48 and Counter<=96) THEN Counter<=00;
ELSIF(Counter>=97) THEN Counter<=48;
END IF;
ELSIF(NEXTONE='0' AND LASTONE='0' AND PREVIOUS='1') THEN --选择本首重放,将计数器改为本首开始的状态数
IF(Counter<=47) THEN Counter<=00;
ELSIF(Counter>=48 and Counter<=96) THEN Counter<=48;
ELSIF(Counter>=97) THEN Counter<=97;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clk) --歌曲序号显示,通过状态数的大小判断
BEGIN
if(reset3='1')then
chushi<="000000000000000";
elsif(reset3='0')then
if(clk3'event and clk3='1')then
chushi<=chushi+1;
end if;
end if;
gaowei(1 downto 0)<=chushi(14 downto 13);
diwei(2 downto 0)<=chushi(2 downto 0);
case diwei is --xianshihang
when"000"=>lie3<="01111111";
when"001"=>lie3<="10111111";
when"010"=>lie3<="11011111";
when"011"=>lie3<="11101111";
when"100"=>lie3<="11110111";
when"101"=>lie3<="11111011";
when"110"=>lie3<="11111101";
when"111"=>lie3<="11111110";
end case;
if gaowei="00"then --waiquanhongxin
hangnew3<="00000000";
case diwei is
when"000"=>hang3<="01100110";
when"001"=>hang3<="10011001";
when"010"=>hang3<="10000001";
when"011"=>hang3<="10000001";
when"100"=>hang3<="10000001";
when"101"=>hang3<="01000010";
when"110"=>hang3<="00100100";
when"111"=>hang3<="00011000";
end case;
elsif gaowei="01"then --xianshi0
case diwei is
when"000"=>hang3<="00000000";hangnew3<="00000000";
when"001"=>hang3<="00100100";hangnew3<="00100100";
when"010"=>hang3<="01011010";hangnew3<="01011010";
when"011"=>hang3<="01000010";hangnew3<="01000010";
when"100"=>hang3<="01000010";hangnew3<="01000010";
when"101"=>hang3<="00100100";hangnew3<="00100100";
when"110"=>hang3<="00011000";hangnew3<="00011000";
when"111"=>hang3<="00000000";hangnew3<="00000000";
end case;
elsif gaowei="10"then --xianshi1
case diwei is
when"000"=>hangnew3<="00000000";hang3<="00000000";
when"001"=>hangnew3<="00000000";hang3<="00000000";
when"010"=>hangnew3<="00100100";hang3<="00000000";
when"011"=>hangnew3<="00111100";hang3<="00000000";
when"100"=>hangnew3<="00111100";hang3<="00000000";
when"101"=>hangnew3<="00011000";hang3<="00000000";
when"110"=>hangnew3<="00000000";hang3<="00000000";
when"111"=>hangnew3<="00000000";hang3<="00000000";
end case;
elsif gaowei="11"then --xian shi1
case diwei is
when"000"=>hang3<="01100110";hangnew3<="00000000";
when"001"=>hang3<="10111101";hangnew3<="00100100";
when"010"=>hang3<="11011011";hangnew3<="01111110";
when"011"=>hang3<="11000011";hangnew3<="01111110";
when"100"=>hang3<="11000011";hangnew3<="01111110";
when"101"=>hang3<="01100110";hangnew3<="00111100";
when"110"=>hang3<="00111100";hangnew3<="00011000";
when"111"=>hang3<="00011000";hangnew3<="00000000";
end case;
end if;
IF Counter<=47 THEN CAT<="011111"; --之让第一个7段数码管显示歌曲序号
SEG<="0110000";
ELSIF Counter>=48 AND Counter<=96 THEN CAT<="101111";
SEG<="1101101";
ELSIF Counter>=97 THEN CAT<="110111";
SEG<="1111001";
END IF;
END PROCESS;
Search : PROCESS(Counter)
BEGIN
CASE Counter IS
WHEN 0 =>ToneIndex <=15; --第一首歌《小星星》
WHEN 1 =>ToneIndex <=15;
WHEN 2 =>ToneIndex <=0;
WHEN 3 =>ToneIndex <=14;
WHEN 4 =>ToneIndex <=14;
WHEN 5 =>ToneIndex <=0;
WHEN 6 =>ToneIndex <=13;
WHEN 7 =>ToneIndex <=13;
WHEN 8 =>ToneIndex <=0;
WHEN 9 =>ToneIndex <=12;
WHEN 10 =>ToneIndex <=12;
WHEN 11 =>ToneIndex <=0;
WHEN 12 =>ToneIndex <=11;
WHEN 13 =>ToneIndex <=11;
WHEN 14 =>ToneIndex <=0;
WHEN 15 =>ToneIndex <=10;
WHEN 16 =>ToneIndex <=10;
WHEN 17 =>ToneIndex <=0;
WHEN 18 =>ToneIndex <=9;
WHEN 19 =>ToneIndex <=9;
WHEN 20 =>ToneIndex <=0;
WHEN 21 =>ToneIndex <=8;
WHEN 22 =>ToneIndex <=8;
WHEN 23 =>ToneIndex <=0;
WHEN 24 =>ToneIndex <=7;
WHEN 25 =>ToneIndex <=7;
WHEN 26 =>ToneIndex <=0;
WHEN 27 =>ToneIndex <=6;
WHEN 28 =>ToneIndex <=6;
WHEN 29 =>ToneIndex <=0;
WHEN 30 =>ToneIndex <=5;
WHEN 31 =>ToneIndex <=5;
WHEN 32 =>ToneIndex <=0;
WHEN 33 =>ToneIndex <=4;
WHEN 34 =>ToneIndex <=4;
WHEN 35 =>ToneIndex <=0;
WHEN 36 =>ToneIndex <=3;
WHEN 37 =>ToneIndex <=3;
WHEN 38 =>ToneIndex <=0;
WHEN 39 =>ToneIndex <=2;
WHEN 40 =>ToneIndex <=2;
WHEN 41 =>ToneIndex <=0;
WHEN 42 =>ToneIndex <=1;
WHEN 43 =>ToneIndex <=1;
WHEN 44 =>ToneIndex <=0;
WHEN 45 =>ToneIndex <=0;
WHEN 46 =>ToneIndex <=0;
WHEN 47 =>ToneIndex <=0;
WHEN 48 =>ToneIndex <=10; --第二首歌《雪融花》
WHEN 49 =>ToneIndex <=10;
WHEN 50 =>ToneIndex <=10;
WHEN 51 =>ToneIndex <=10;
WHEN 52 =>ToneIndex <=12;
WHEN 53 =>ToneIndex <=12;
WHEN 54 =>ToneIndex <=15;
WHEN 55 =>ToneIndex <=15;
WHEN 56 =>ToneIndex <=15;
WHEN 57 =>ToneIndex <=15;
WHEN 58 =>ToneIndex <=15;
WHEN 59 =>ToneIndex <=15;
WHEN 60 =>ToneIndex <=15;
WHEN 61 =>ToneIndex <=15;
WHEN 62 =>ToneIndex <=15;
WHEN 63 =>ToneIndex <=15;
WHEN 64 =>ToneIndex <=12;
WHEN 65 =>ToneIndex <=12;
WHEN 66 =>ToneIndex <=11;
WHEN 67 =>ToneIndex <=11;
WHEN 68 =>ToneIndex <=11;
WHEN 69 =>ToneIndex <=11;
WHEN 70 =>ToneIndex <=11;
WHEN 71 =>ToneIndex <=11;
WHEN 72 =>ToneIndex <=10;
WHEN 73 =>ToneIndex <=10;
WHEN 74 =>ToneIndex <=10;
WHEN 75 =>ToneIndex <=10;
WHEN 76 =>ToneIndex <=10;
WHEN 77 =>ToneIndex <=10;
WHEN 78 =>ToneIndex <=10;
WHEN 79 =>ToneIndex <=10;
WHEN 80 =>ToneIndex <=11;
WHEN 81 =>ToneIndex <=11;
WHEN 82 =>ToneIndex <=12;
WHEN 83 =>ToneIndex <=12;
WHEN 84 =>ToneIndex <=13;
WHEN 85 =>ToneIndex <=13;
WHEN 86 =>ToneIndex <=13;
WHEN 87 =>ToneIndex <=13;
WHEN 88 =>ToneIndex <=13;
WHEN 89 =>ToneIndex <=13;
WHEN 90 =>ToneIndex <=12;
WHEN 91 =>ToneIndex <=12;
WHEN 92 =>ToneIndex <=12;
WHEN 93 =>ToneIndex <=12;
WHEN 94 =>ToneIndex <=12;
WHEN 95 =>ToneIndex <=12;
WHEN 96 =>ToneIndex <=10;
WHEN 97 =>ToneIndex <=5; --第三首歌《童话》
WHEN 98 =>ToneIndex <=12;
WHEN 99 =>ToneIndex <=11;
WHEN 100 =>ToneIndex <=10;
WHEN 101 =>ToneIndex <=10;
WHEN 102 =>ToneIndex <=10;
WHEN 103 =>ToneIndex <=11;
WHEN 104 =>ToneIndex <=10;
WHEN 105 =>ToneIndex <=10;
WHEN 106 =>ToneIndex <=10;
WHEN 107 =>ToneIndex <=11;
WHEN 108 =>ToneIndex <=10;
WHEN 109 =>ToneIndex <=11;
WHEN 110 =>ToneIndex <=10;
WHEN 111 =>ToneIndex <=9;
WHEN 112 =>ToneIndex <=0;
WHEN 113 =>ToneIndex <=8;
WHEN 114 =>ToneIndex <=10;
WHEN 115 =>ToneIndex <=12;
WHEN 116 =>ToneIndex <=13;
WHEN 117 =>ToneIndex <=13;
WHEN 118 =>ToneIndex <=13;
WHEN 119 =>ToneIndex <=12;
WHEN 120 =>ToneIndex <=12;
WHEN 121 =>ToneIndex <=9;
WHEN 122 =>ToneIndex <=9;
WHEN 123 =>ToneIndex <=11;
WHEN 124 =>ToneIndex <=10;
WHEN 125 =>ToneIndex <=10;
WHEN 126 =>ToneIndex <=10;
WHEN 127 =>ToneIndex <=10;
WHEN 128 =>ToneIndex <=0;
WHEN 129 =>ToneIndex <=8;
WHEN 130 =>ToneIndex <=10;
WHEN 131 =>ToneIndex <=12;
WHEN 132 =>ToneIndex <=13;
WHEN 133 =>ToneIndex <=13;
WHEN 134 =>ToneIndex <=13;
WHEN 135 =>ToneIndex <=12;
WHEN 136 =>ToneIndex <=12;
WHEN 137 =>ToneIndex <=9;
WHEN 138 =>ToneIndex <=9;
WHEN 139 =>ToneIndex <=11;
WHEN 140 =>ToneIndex <=10;
WHEN 141 =>ToneIndex <=11;
WHEN 142 =>ToneIndex <=10;
WHEN 143 =>ToneIndex <=9;
WHEN 144 =>ToneIndex <=8;
WHEN 145 =>ToneIndex <=8;
WHEN 146 =>ToneIndex <=9;
WHEN 147 =>ToneIndex <=10;
WHEN 148 =>ToneIndex <=6;
WHEN 149 =>ToneIndex <=6;
WHEN 150 =>ToneIndex <=6;
WHEN 151 =>ToneIndex <=8;
WHEN 152 =>ToneIndex <=8;
WHEN OTHERS =>NULL;
END CASE;
END PROCESS;
END;
C.音调发声ToneT
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
ENTITY ToneT IS
PORT ( Index: IN INTEGER RANGE 0 TO 15;
LED: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
Tone: OUT INTEGER RANGE 0 TO 16#7FF#);
END;
ARCHITECTURE one OF ToneT IS
BEGIN
Search : PROCESS(Index)
BEGIN
CASE Index IS --音调分频比
WHEN 0=>Tone<= 0;
WHEN 1=>Tone<= 1318; LED<="1000000";--1
WHEN 2=>Tone<= 1174; LED<="0100000";--7
WHEN 4=>Tone<= 1045; LED<="0001000";--6
WHEN 3=>Tone<= 987; LED<="0010000";--5
WHEN 5=>Tone<= 880; LED<="0000100";--4
WHEN 6=>Tone<= 783; LED<="0000010";--3
WHEN 7=>Tone<= 698; LED<="0000001";--2
WHEN 8=>Tone<= 659; LED<="1000000";--1
WHEN 9=>Tone<= 587; LED<="0100000";--7
WHEN 10=>Tone<=523; LED<="0010000";--6
WHEN 11=>Tone<=493; LED<="0001000";--5
WHEN 12=>Tone<=440; LED<="0000100";--4
WHEN 13=>Tone<=391; LED<="0000010";--3
WHEN 14=>Tone<=349; LED<="0000001";--2
WHEN 15=>Tone<=329; LED<="1000000";--1
WHEN OTHERS =>NULL;
END CASE;
END PROCESS;
END;
D,数控分频Speakera
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
ENTITY Speakera IS
PORT ( clk :IN STD_LOGIC; --1MHz
Tone : IN INTEGER RANGE 0 TO 16#7FF#; --音调分频比率
Spks :OUT STD_LOGIC ); --频率输出给蜂鸣器
END;
ARCHITECTURE one OF Speakera IS
SIGNAL PreCLK : STD_LOGIC;
SIGNAL FullSpks : STD_LOGIC;
BEGIN
DivideCLK : PROCESS(clk)
VARIABLE COUNT4: INTEGER RANGE 0 TO 8;
BEGIN
IF(CLK'EVENT AND CLK='1')THEN
COUNT4:=COUNT4+1;
IF COUNT4=2 THEN
PRECLK<='1';
ELSIF COUNT4=4 THEN
PRECLK<='0';COUNT4:=0;
END IF;
END IF;
END PROCESS;
GenSpks : PROCESS (PreCLK,Tone)
VARIABLE Count11 : INTEGER RANGE 0 TO 16#7FF#;
BEGIN
IF PreCLK'EVENT AND PreCLK='1' THEN --按分频比分频
IF Count11 = Tone THEN
Count11 :=0;
FullSpks <='1';
ELSE Count11 := Count11 +1;
FullSpks <='0'; END IF;
END IF;
END PROCESS;
DelaySpks : PROCESS (FullSpks)
VARIABLE Count2 : STD_LOGIC;
BEGIN
IF FullSpks'EVENT AND FullSpks='1' THEN --D触发器2分频,保证蜂鸣器发声稳定
Count2:= NOT Count2 ;
IF Count2 ='1' THEN Spks <='1';
ELSE Spks <='0'; END IF;
END IF;
END PROCESS;
END;
E.点阵显示模块
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;
entity dianzhenxianshixs is
port( clk3,reset3:in std_logic;
hang3ut std_logic_vector(7 downto 0);
hangnew3ut std_logic_vector(7 downto 0);
lie3ut std_logic_vector(7 downto 0));
end dianzhenxianshixs;
architecture jg of dianzhenxianshixs is
signal chushi:std_logic_vector(14 downto 0):="000000000000000";
signal gaowei:std_logic_vector(1 downto 0);
signal diwei:std_logic_vector(2 downto 0);
begin
process(clk3,diwei,chushi,gaowei,reset3)
begin
if(reset3='1')then
chushi<="000000000000000";
elsif(reset3='0')then
if(clk3'event and clk3='1')then
chushi<=chushi+1;
end if;
end if;
gaowei(1 downto 0)<=chushi(14 downto 13);
diwei(2 downto 0)<=chushi(2 downto 0);
case diwei is --xianshihang
when"000"=>lie3<="01111111";
when"001"=>lie3<="10111111";
when"010"=>lie3<="11011111";
when"011"=>lie3<="11101111";
when"100"=>lie3<="11110111";
when"101"=>lie3<="11111011";
when"110"=>lie3<="11111101";
when"111"=>lie3<="11111110";
end case;
if gaowei="00"then --waiquanhongxin
hangnew3<="00000000";
case diwei is
when"000"=>hang3<="01100110";
when"001"=>hang3<="10011001";
when"010"=>hang3<="10000001";
when"011"=>hang3<="10000001";
when"100"=>hang3<="10000001";
when"101"=>hang3<="01000010";
when"110"=>hang3<="00100100";
when"111"=>hang3<="00011000";
end case;
elsif gaowei="01"then --xianshi0
case diwei is
when"000"=>hang3<="00000000";hangnew3<="00000000";
when"001"=>hang3<="00100100";hangnew3<="00100100";
when"010"=>hang3<="01011010";hangnew3<="01011010";
when"011"=>hang3<="01000010";hangnew3<="01000010";
when"100"=>hang3<="01000010";hangnew3<="01000010";
when"101"=>hang3<="00100100";hangnew3<="00100100";
when"110"=>hang3<="00011000";hangnew3<="00011000";
when"111"=>hang3<="00000000";hangnew3<="00000000";
end case;
elsif gaowei="10"then --xianshi1
case diwei is
when"000"=>hangnew3<="00000000";hang3<="00000000";
when"001"=>hangnew3<="00000000";hang3<="00000000";
when"010"=>hangnew3<="00100100";hang3<="00000000";
when"011"=>hangnew3<="00111100";hang3<="00000000";
when"100"=>hangnew3<="00111100";hang3<="00000000";
when"101"=>hangnew3<="00011000";hang3<="00000000";
when"110"=>hangnew3<="00000000";hang3<="00000000";
when"111"=>hangnew3<="00000000";hang3<="00000000";
end case;
elsif gaowei="11"then --xian shi1
case diwei is
when"000"=>hang3<="01100110";hangnew3<="00000000";
when"001"=>hang3<="10111101";hangnew3<="00100100";
when"010"=>hang3<="11011011";hangnew3<="01111110";
when"011"=>hang3<="11000011";hangnew3<="01111110";
when"100"=>hang3<="11000011";hangnew3<="01111110";
when"101"=>hang3<="01100110";hangnew3<="00111100";
when"110"=>hang3<="00111100";hangnew3<="00011000";
when"111"=>hang3<="00011000";hangnew3<="00000000";
end case;
end if;
end process;
end ;第4部分 实验结果
4.1 实验操作过程
下载完成后自动播放音乐,sw0置于0,顺序播放,使用btn7重听本首音乐,btn6下一首,btn5上一首,sw0置于1,则进入随机播放功能。Sw1置于1,自动播放歌曲1,sw2置于1,播放歌曲2,sw3置于1,播放歌曲3.sw4置于1,进入自动弹奏模式,btn0~btn4控制自动发音1,2,3,4,5. Sw7控制停止和继续,并且同时控制点阵图形的出现和消失。
4.2 实验结果截图
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps10.png
播放时点阵显示跳动的心脏,数码管显示播放曲目
4.3 仿真原理图(未仿真点阵)
播放模式
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps11.jpg
由仿真图可以看出来
在顺序播放模式下按下next切换到下一首, 按下lastone切换到上一首,按下previous播放本首
在随机模式下,按下3个键都会随机播放一首歌曲
弹奏模式
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps12.jpg
按下1,2,3,4,5 这几个不同的音符,数码管显示不同的数字
按下停止,音乐播放器停止播放
4.4 资源利用率
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps13.jpg
4.5实验总结
4.5.1实验遇到的故障及问题
本次实验遇到的问题还是很多的,主要原因是把EDA, VHDL看得太过简单了,但其实本质上对它还是不太熟悉的。
软件上遇到的问题主要涉及编程方面。比如开始的时候对自顶向下的模式不是很理解,后来才明白这是便于分块处理,在使用portmap时经常发生变量对应错误的情况,我发现,这是因为我把名字都取得太容易混淆了,导致参量一多,连自己都分不清楚了。
硬件上遇到的问题有,对于老式实验板,许多蜂鸣器的开关都没有了,导致蜂鸣器不能使用。于是从不用蜂鸣器的同学那要了个黑色小开关来。后来发现点阵也不能用,用别的板子试验发现程序没有问题,所以直接换了块实验板,问题解决。
4.5.2实验感想总结
这四周进行了VHDL状态机和自顶向下设计方法的学习,通过本次实验更加了解了EDA,更加熟悉了VHDL的基本编程方法,特别是在实验过程中,锻炼了自己的动手能力,独立思考能力,从而增强了自主学习能力。
正如实验遇到的问题中所描述的那样,我在实验过程中其实是不断摸索的。记得最清楚的就是当音乐怎么也不响时郁闷的心情,我们在一再确认程序无误的情况下只能说是素手无策,实验一度度陷入僵局。在各处搜索结果无望的情况下,我们和身边同学进行了讨论,最后找到了问题原来是板子上有个小开关不见了。这让我明白自身能力的有限,能及时求助他人是十分有效的做法。
我的作品仍有瑕疵,由于时间等多方面原因没有进行进一步修改,比如停止时会一直叫高音而不是停下来不唱了。而且有许多想要增加实现的功能最后都没有实现,但是在这样不断的思考,不断的实践的过程中,我觉得获得的远多于一个小小的音乐播放器,希望自己能学会反思,以后能更有条理,这样才能更加高效的学习的更多。
第5部分 附录
5.1.材料清单
EMP1270-144c5实验板一块
file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml7864\wps14.png
5.2.参考书目
《EDA技术与实践》.机械工业出版社, 2004年7月李国洪.沈明山.
《EDA技术及可编程器件应用实例》.科学出版社,2004年10月沈明山
《VHDL实例教程》
《数字逻辑设计实验与EDA技术》
《EDA应用实例》
感谢百度百科提供的解答
|
|