沈阳工程学院课程设计(论文)
END PROCESS; END;
仿真波形如下:
图3.3 音乐节拍发生器仿真波形
原器件符号:
图3.4 音乐发生器元件符号
3.3.2音符译码电路ToneTaba模块
音符译码电路即音调发生器实际上是一个翻译电路,根据输入为数控分频模块提供所发音符频率的初始值,而此数控分频模块入口的停留时间即为此音符的节拍数,以VHDL程序中仅设置了“梁祝”乐曲全部音符所对应的音符频率的初始值。
//CLK_4HZ: 用于控制音长(节拍)的时钟频率; //CLK_6MHZ:用于产生各种音阶频率的基准频率;
//SPEAKER: 用于激励扬声器的输出信号,本例中为方波信号; //HIGH, MED, LOW:分别用于显示高音、中音和低音音符,各驱动一个数码来显示。
其VHDL源程序如下: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL; ENTITY ToneTaba IS
PORT ( Index : IN INTEGER RANGE 0 TO 15; CODE : OUT INTEGER RANGE 0 TO 15;
- 14 -
沈阳工程学院课程设计(论文)
HIGH : OUT STD_LOGIC;
Tone : OUT INTEGER RANGE 0 TO 16#7FF# ); END;
ARCHITECTURE one OF ToneTaba IS BEGIN
Search : PROCESS(Index) BEGIN
CASE Index IS -- 译码电路,查表方式,控制音调的预置数 WHEN 0 => Tone <= 2047; CODE <= 0; HIGH <= '0'; WHEN 1 => Tone <= 773; CODE <= 1; HIGH <= '0'; WHEN 2 => Tone <= 912; CODE <= 2; HIGH <= '0'; WHEN 3 => Tone <= 1036; CODE <= 3; HIGH <= '0'; WHEN 5 => Tone <= 1197; CODE <= 5; HIGH <= '0'; WHEN 6 => Tone <= 1290; CODE <= 6; HIGH <= '0'; WHEN 7 => Tone <= 1372; CODE <= 7; HIGH <= '0'; WHEN 8 => Tone <= 1410; CODE <= 1; HIGH <= '1'; WHEN 9 => Tone <= 1480; CODE <= 2; HIGH <= '1'; WHEN 10 => Tone <= 1542; CODE <= 3; HIGH <= '1'; WHEN 12 => Tone <= 1622; CODE <= 5; HIGH <= '1'; WHEN 13 => Tone <= 1668; CODE <= 6; HIGH <= '1'; WHEN 15 => Tone <= 1728; CODE <= 7; HIGH <= '1'; WHEN OTHERS => NULL; END CASE; END PROCESS; END;
在源程序中Index是音乐节拍发生器输出的音符数据;TONE是为数控分频模块提供的音符频率的初始值,为方便测试,特设置了一个音名代码显示输出CODE和音高指示信号HUGH可以通过数码管或LED来显示乐曲演奏时对应的音符和高音名。CODE输出对应该音阶简谱的显示数码1,HIGH输出为高电平,指示音阶为高,HIGH输出为低电平时,则指示音阶为中音。低音时,Tone值小,分频比大,进位信号SPKS的周期长。
仿真波形如下:
- 15 -
沈阳工程学院课程设计(论文)
图3.5音符译码器的仿真输出波形
图3.6音符译码器的元件符号图
3.3.3数控分频模块(Speakera)设计
数控分频器对FPGA的基准频率进行分频,得到与各个音阶对应的频率输出。数控分频模块是13位的加法计数器构成。当计数器计满是,产生一个进位信号FULLSPKS,该信号就是用作发音的频率信号。在即使器的预置端给定不同的初始值,其输出将产生不同的频率信号,频率信号初值Tone就是前级音符译码电路的输出。低音时,Tone值小,分频比大,进位信号SPKS的周期长,扬声器发出的声音低,Tone随音乐的乐谱而变化,自动控制分频比,从而实现数控分频,发生信号的频率与Tone成正比,这就是利用数控分频器演奏音乐的原理。
通过分频后其进位信号FULLSPJKS是一周期脉冲信号,为有利于驱动扬声器,在音调输出时再进行2分频,将脉冲展宽,使之占空比为50%,扬声器这样就有足够的发声功率。
其VHDL源程序如下: LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
- 16 -
沈阳工程学院课程设计(论文)
ENTITY Speakera IS
PORT ( clk : IN STD_LOGIC;
Tone : IN INTEGER RANGE 0 TO 16#1FFF#; 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 15; BEGIN
PreCLK <= '0';
-- 将CLK进行16分频,PreCLK为CLK的16分频 IF Count4 > 11 THEN PreCLK <= '1'; Count4 := 0;
ELSIF clk'EVENT AND clk = '1' THEN Count4 := Count4 + 1; END IF; END PROCESS;
GenSpkS : PROCESS(PreCLK, Tone)
VARIABLE Count13: INTEGER RANGE 0 TO 16#1FFF#; BEGIN
-- 13位可预置计数器
IF PreCLK'EVENT AND PreCLK = '1' THEN IF Count13 = 16#1FFF# THEN Count13 := Tone;
FullSpkS <= '1'; ELSE
Count13 := Count13 + 1;
FullSpkS <= '0'; END IF; END IF; END PROCESS;
DelaySpkS : PROCESS(FullSpkS)
VARIABLE Count2 : STD_LOGIC; BEGIN
- 17 -
沈阳工程学院课程设计(论文)
-- 将输出再进行2分频,将脉冲展宽,以使扬声器有足够功率发音
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;
VHDL程序的第1个进程首先对FPGA的时基脉冲Tone输入的分频系数进行分频,得到所需要的音符频率;第2个进程的作用是在音调输出时再进行2分频,将脉冲展宽,使扬声器有足够发生功率。
仿真图形如下:
图3.7数控分频器仿真波形
图3.8 分频器元件符号
- 18 -