音乐发生器设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验项目五音乐发生器设计
一、实验目的
1、了解普通扬声器的工作原理。
2、使用FPGA产生不同的音乐频率。
3、进一步体验FPGA的灵活性。
1、
二、硬件要求
1、EDA2000实验箱(其他厂家具有同等配置试验箱均可)
2、主芯片:EP1K1OTC100-3
3、计算机与QUARTUS 软件
三、实验原理
1、乐曲的发声原理:组成乐曲的2个基本要素是:每个音符的发音频率值及其持续的时间(节奏)。一般人能听到声音的频率范围约在几十到几千赫兹,可以利用程序控制FPGA 某个引脚输出一定频率的矩形波,接上扬声器后就能发出相应频率的声音,演奏某个音符的音调,同时,若能控制每个音符的持续时间,也就控制了乐曲的节奏,因此只要控制输出到扬声器的信号频率的高低以及每个信号的持续时间长短,即可实现乐曲的演奏。
2、音符的产生:音符的产生是利用计数器对输入的时钟信号进行分频,然后输出不同的频率来控制扬声器发不同的声音。计数器必须是模可变的计数器,也就是其初始计数值可变,这样便可以对其进行初始化,使其从不同的初始值开始计数,实现对输入时钟信号的不同分频。
3、节拍的产生:节拍也是利用计数器来实现,如果某一个音符需要维持的时间比较长,那么就可以在此计数器从计数值A到计数值B之间都维持该音符,很显然,A和B之间的间隔越大,那么该音符维持的时间也就越长。
4、乐谱的存储:乐谱是一个固定的组合电路,根据不同的输入值,然后输出一个固定的值,该值就是音符产生计数器的分频的初始值。
5、适当的选择这些计数器和组合电路,便可完成不同的乐曲和不同节奏。
四、实验内容及步骤
本实验要完成的任务是设计一个驱动扬声器产生梁祝音乐的程序,设计步骤如下:
1、编写音乐输出的VHDL代码。
2、用Quartus II对其进行编译仿真。
3、在仿真确定无误后,选择芯片ACEX1K EP1K10TC100-3。
4、给芯片进行管脚绑定,在此进行编译。
5、根据自己绑定的管脚,在实验箱上对扬声器接口和FPGA之间进行正确连线。
6、给目标板下载代码,观看实验结果。
五、下面为梁祝音乐代码,要求讲其改写为上海滩代码,并在EDA2000上下载验证LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY song IS
PORT(
clk_4MHz,clk_4Hz: IN STD_LOGIC; --预置计数器和乐谱产生器的时钟digit: BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0); --高、中、低音数码管指示
zero:OUT STD_LOGIC_VECTOR(4 DOWNTO 0); --用于数码管高位置低
speaker: out STD_LOGIC --扬声器
);
END song;
ARCHITECTURE song_arch OF song IS
SIGNAL divider,origin:STD_LOGIC_VECTOR(12 DOWNTO 0); --13位计数值和预置值
SIGNAL counter:integer range 0 to 140; --7位计数器
SIGNAL count:STD_LOGIC_VECTOR(1 DOWNTO 0); --记录1/4拍
SIGNAL carrier:STD_LOGIC;
BEGIN
zero<="00000";
PROCESS(clk_4MHz)
BEGIN
IF(clk_4MHz'event AND clk_4MHz='1') THEN
IF(divider="1111111111111") THEN
carrier<='1';
divider<=origin;
ELSE
divider<=divider+'1';
carrier<='0';
END IF;
END IF;
END PROCESS;
PROCESS(carrier)
BEGIN
IF(carrier'event AND carrier='1') THEN
count<=count+'1'; --输出时钟四分频
IF count="00" THEN
speaker<='1';
ELSE
speaker<='0';
END IF;
END IF;
END PROCESS;
PROCESS(clk_4Hz)
BEGIN
IF(clk_4Hz'event AND clk_4Hz='1') THEN
IF(counter=140) THEN
counter<=0;
ELSE
counter<=counter+1;
END IF;
END IF;
CASE counter IS
WHEN 0=>digit<="0000011"; WHEN 1=>digit<="0000011";
WHEN 2=>digit<="0000011"; WHEN 3=>digit<="0000011";
WHEN 4=>digit<="0000101"; WHEN 5=>digit<="0000101";
WHEN 6=>digit<="0000101"; WHEN 7=>digit<="0000110";
WHEN 8=>digit<="0001000"; WHEN 9=>digit<="0001000";
WHEN 10=>digit<="0001000"; WHEN 11=>digit<="0010000";
WHEN 12=>digit<="0000110"; WHEN 13=>digit<="0001000"; WHEN 14=>digit<="0000101"; WHEN 15=>digit<="0000101";
WHEN 16=>digit<="0101000"; WHEN 17=>digit<="0101000";
WHEN 18=>digit<="0101000"; WHEN 19=>digit<="1000000";
WHEN 20=>digit<="0110000"; WHEN 21=>digit<="0101000"; WHEN 22=>digit<="0011000"; WHEN 23=>digit<="0101000";
WHEN 24=>digit<="0010000"; WHEN 25=>digit<="0010000";
WHEN 26=>digit<="0010000"; WHEN 27=>digit<="0010000";
WHEN 28=>digit<="0010000"; WHEN 29=>digit<="0010000";
WHEN 30=>digit<="0010000"; WHEN 31=>digit<="0000000";
WHEN 32=>digit<="0010000"; WHEN 33=>digit<="0010000";
WHEN 34=>digit<="0010000"; WHEN 35=>digit<="0011000";
WHEN 36=>digit<="0000111"; WHEN 37=>digit<="0000111";
WHEN 38=>digit<="0000110"; WHEN 39=>digit<="0000110";
WHEN 40=>digit<="0000101"; WHEN 41=>digit<="0000101";
WHEN 42=>digit<="0000101"; WHEN 43=>digit<="0000110"; WHEN 44=>digit<="0001000"; WHEN 45=>digit<="0001000";
WHEN 46=>digit<="0010000"; WHEN 47=>digit<="0010000";
WHEN 48=>digit<="0000011"; WHEN 49=>digit<="0000011";
WHEN 50=>digit<="0001000"; WHEN 51=>digit<="0001000";
WHEN 52=>digit<="0000110"; WHEN 53=>digit<="0000101";
WHEN 54=>digit<="0000110"; WHEN 55=>digit<="0001000";
WHEN 56=>digit<="0000101"; WHEN 57=>digit<="0000101";
WHEN 58=>digit<="0000101"; WHEN 59=>digit<="0000101";
WHEN 60=>digit<="0000101"; WHEN 61=>digit<="0000101";
WHEN 62=>digit<="0000101"; WHEN 63=>digit<="0000101"; WHEN 64=>digit<="0011000"; WHEN 65=>digit<="0011000";
WHEN 66=>digit<="0011000"; WHEN 67=>digit<="0101000";
WHEN 68=>digit<="0000111"; WHEN 69=>digit<="0000111";
WHEN 70=>digit<="0010000"; WHEN 71=>digit<="0010000"; WHEN 72=>digit<="0000110"; WHEN 73=>digit<="0001000"; WHEN 74=>digit<="0000101"; WHEN 75=>digit<="0000101";
WHEN 76=>digit<="0000101"; WHEN 77=>digit<="0000101";
WHEN 78=>digit<="0000101"; WHEN 79=>digit<="0000101";
WHEN 80=>digit<="0000011"; WHEN 81=>digit<="0000101";