|
本帖最后由 zxopenyz 于 2020-1-10 09:07 编辑
附录
源程序如下:
1、自动演奏模块程序(AUTO.VHD):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY AUTO IS
PORT ( CLK : IN STD_LOGIC; --系统时钟;键盘输入/自动演奏
AUTO : IN STD_LOGIC;  --键盘输入信号 
CLK2 : BUFFER STD_LOGIC; --音符信号输出
INDEX2 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
INDEX0 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END AUTO;
ARCHITECTURE BEHAVIORAL OF AUTO IS
SIGNAL COUNT0: INTEGER RANGE 0 TO 31;
BEGIN
PULSE0 : PROCESS(CLK,AUTO)  
--此进程完成对系统时钟8M的分频,得到4Hz的信号clk2
VARIABLE COUNT :INTEGER RANGE 0 TO 8;
--定义计数器变量,值从0到8
BEGIN
IF AUTO ='1' THEN --键盘输入为1
COUNT := 0;CLK2<='0'; --计数器值指0,时钟信号为0
ELSIF(CLK'EVENT AND CLK ='1')THEN --时钟输入信号为1
COUNT :=COUNT +1; --计数器加1
IF COUNT =4 THEN
CLK2 <='1';
ELSIF COUNT =8 THEN
CLK2<='0'; COUNT:=0;
END IF ;
END IF ;
END PROCESS;
MUSIC: PROCESS(CLK2) --此进程完成自动演奏部分曲的地址累加
BEGIN
IF (CLK2'EVENT AND CLK2='1')THEN
IF (COUNT0=31)THEN
COUNT0<=0;
ELSE
COUNT0<=COUNT0+1;
END IF ;
END IF ;
END PROCESS;
COM1: PROCESS(COUNT0,AUTO,INDEX2)
BEGIN
IF AUTO ='0' THEN
CASE COUNT0 IS --此case语句:存储自动演奏部分的曲
WHEN 0=>INDEX0<="00000100"; --3
WHEN 1=>INDEX0<="00000100"; --3
WHEN 2=>INDEX0<="00000100"; --3
WHEN 3=>INDEX0<="00000100"; --3
WHEN 4=>INDEX0<="00010000"; --5
WHEN 5=>INDEX0<="00010000"; --5
WHEN 6=>INDEX0<="00010000"; --5
WHEN 7=>INDEX0<="00100000"; --6
WHEN 8=>INDEX0<="10000000"; --8
WHEN 9=>INDEX0<="10000000"; --8
WHEN 10=>INDEX0<="10000000"; --8
WHEN 11=>INDEX0<="00000100"; --3
WHEN 12=>INDEX0<="00000010"; --2
WHEN 13=>INDEX0<="00000010"; --2
WHEN 14=>INDEX0<="00000001"; --1
WHEN 15=>INDEX0<="00000001"; --1
WHEN 16=>INDEX0<="00010000"; --5
WHEN 17=>INDEX0<="00010000"; --5
WHEN 18=>INDEX0<="00001000"; --4
WHEN 19=>INDEX0<="00001000"; --4
WHEN 20=>INDEX0<="00001000"; --4
WHEN 21=>INDEX0<="00000100"; --3
WHEN 22=>INDEX0<="00000010"; --2
WHEN 23=>INDEX0<="00000010"; --2
WHEN 24=>INDEX0<="00010000"; --5
WHEN 25=>INDEX0<="00010000"; --5
WHEN 26=>INDEX0<="00001000"; --4
WHEN 27=>INDEX0<="00001000"; --4
WHEN 28=>INDEX0<="00000100"; --3
WHEN 29=>INDEX0<="00000100"; --3
WHEN 30=>INDEX0<="00000010"; --2
WHEN 31=>INDEX0<="00000010"; --2
WHEN OTHERS =>NULL;
END CASE;
ELSE INDEX0<=INDEX2; --此进程完成自动演奏部分曲的地址累加
END IF;
END PROCESS;
END BEHAVIORAL;
2、数控分频模块程序(FENPIN.VHD):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY FENPIN IS
PORT(CLK1: IN STD_LOGIC; --定义系统时钟
TONE1: IN INTEGER RANGE 0 TO 2047;
--定义音符分频系数,从0到2047Hz
SPKS: OUT STD_LOGIC); --定义驱动扬声器的音频信号
END ENTITY FENPIN;
ARCHITECTURE ART OF FENPIN IS
SIGNAL PRECLK:STD_LOGIC;
SIGNAL FULLSPKS:STD_LOGIC;
BEGIN
PROCESS(CLK1)
VARIABLE COUNT:INTEGER RANGE 0 TO 8; --此进程对系统时钟进行4分频
BEGIN
IF (CLK1'EVENT AND CLK1='1')THEN
COUNT:=COUNT +1;
IF COUNT=2 THEN
PRECLK<='1';
ELSIF COUNT =4 THEN
PRECLK<='0';COUNT:=0;
END IF ;
END IF ;
END PROCESS;
PROCESS(PRECLK,TONE1) --此进程按照tone1输入
==分频系数对8MHz的脉冲再次分频,得到所需要的音符频率
VARIABLE COUNT11:INTEGER RANGE 0 TO 2047;
BEGIN
IF (PRECLK'EVENT AND PRECLK='1')THEN
IF COUNT11<TONE1 THEN
COUNT11:=COUNT11+1;FULLSPKS<='1';
ELSE
COUNT11:=0;FULLSPKS<='0'; --此进程对FULLSPKS进行2分频
END IF ;
END IF ;
END PROCESS;
PROCESS(FULLSPKS)
VARIABLE COUNT2 :STD_LOGIC:='0';
BEGIN
IF (FULLSPKS'EVENT AND FULLSPKS='1')THEN
COUNT2:=NOT COUNT2;
IF COUNT2='1'THEN
SPKS<='1';
ELSE
SPKS<='0';
END IF ;
END IF;
END PROCESS;
END ART;
3、音调发生模块程序(TONE.VHD):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY TONE IS
PORT (INDEX: IN STD_LOGIC_VECTOR(7 DOWNTO 0); --音符输入信号
CODE: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --音符显示信号
HIGH: OUT STD_LOGIC; --高低音显示信号
TONE0: OUT INTEGER RANGE 0 TO 2047); --音符的分频系数
END TONE;
ARCHITECTURE ART OF TONE IS
BEGIN
SEARCH : PROCESS(INDEX)
--此进程完成音符到音符的分频系数移码,音符的显示,高低音阶。
BEGIN
CASE INDEX IS
WHEN "00000001"=>TONE0 <=773;CODE<="1001111";HIGH<='1';
WHEN "00000010"=>TONE0 <=912;CODE<="0010010";HIGH<='1';
--音符第7位为1,分频数912Hz,音符显示为0010010,属高音
WHEN "00000100"=>TONE0 <=1036;CODE<="0000110";HIGH<='1';
WHEN "00001000"=>TONE0 <=1116;CODE<="1001100";HIGH<='1';
WHEN "00010000"=>TONE0 <=1197;CODE<="0100100";HIGH<='1';
WHEN "00100000"=>TONE0 <=1290;CODE<="0100000";HIGH<='0';
WHEN "01000000"=>TONE0 <=1372;CODE<="0001111";HIGH<='0';
WHEN "10000000"=>TONE0 <=1410;CODE<="0000000";HIGH<='0';
WHEN OTHERS =>TONE0<=2047;CODE<="0000001";HIGH<='0';
END CASE;
END PROCESS;
END ART; |
|