乐曲演奏课程设计报告乐曲演奏电路的设计
北 华 航 天 工 业 学 院《EDA技术综合设计》课程设计报告报告题目: 乐曲演奏电路的设计 作者所在系部: 作者所在专业: 作者所在班级: 作 者 姓 名 : 指导教师姓名: 完 成 时 间 : 内 容 摘 要在EDA开发工具Quartus II 6.0平台上,采用VHDL语言层次化和模块化的设计方法,通过音符编码的设计思想,预先定制乐曲,实现动态显示乐曲演奏电路的设计,并在此基础上,基于同一原理,使此电路同时具备了简易电子琴的功能,使基于CPLD/FPGA芯片的乐曲播放数字电路得到了更好的优化,提高了设计的灵活性和可扩展性关键字:EDA;Quartus II;VHDL;CPLD/FPGA;乐曲演奏电路;简易电子琴课程设计任务书课题名称乐曲演奏电路的设计完成时间2011/12/15指导教师胡辉职称副教授学生姓名宋志朋班 级B09212总体设计要求和技术要点总体设计要求: 通过本课程的学习使学生掌握可编程器件、EDA开发系统软件、硬件描述语言和电子线路设计与技能训练等各方面知识;提高工程实践能力;学会应用EDA技术解决一些简单的电子设计问题。
技术要点:设计一个乐曲演奏电路,由键盘输入控制音响,同时可自动演奏乐曲,演奏时可通过键盘选择已存入的乐曲(3种),扬声器利用试验箱上的利用1位LED显示器显示已存入的乐曲的种类扩展功能:利用发光二极管显示高低音及音节的长短工作内容及时间进度安排第15周:周4:立题、论证方案设计周5:仿真实验周6:验收答辩课程设计成果1.与设计内容对应的软件程序2.课程设计报告书3.成果使用说明书4.设计工作量要求二、设计原理1.1.1 音调的控制频率的高低决定了音调的高低音乐的十二平均率规定:每两个八度音(如简谱中的中音1和高音1)之间的频率相差一倍在两个八度音之间又分为十二个半音另外,音名A(简谱中的低音6)的频率为440Hz,音名B到C之间、E到F之间为半音,其余为全音由此可以计算出简谱中从低音1到高音1之间每个音名对应的频率,所有不同频率的信号都是从同一个基准频率分频得到的由于音阶频率多为非整数,而分频系数又不能为小数,因此必须将计算得到的分频数四舍五入取整若基准频率过低,则由于分频比太小,四舍五入取整后的误差较大;若基准频率过高,虽然误差较小,但分频数将变大实际的设计应综合考虑这两方面的因素,在尽量减小频率误差的前提下取合适的基准频率。
因此,要想FPGA发出不同音符的音调,实际上只要控制它输出相应音符的频率即可综合考虑各因素,本文中选取12MHZ作为CLK的分频计数器的输入分频信号乐曲都是由一连串的音符组成,因此按照乐曲的乐谱依次输出这些音符所对应的频率,就可以在扬声器上连续地发出各个音符的音调表3-1 简谱中的音名与频率的关系音名频率/Hz音名频率/Hz音名频率/Hz低音1261.6中音1523.3高音11045.5低音2293.7中音2587.3高音21174.7低音3329.6中音3659.3高音31318.5低音4349.2中音4698.5高音41396.9低音5392中音5784高音51568低音6440中音6880高音61760低音7493.9中音7987.8高音71975.5资料来源:EPM7128实验板说明书1.1.2 音长的控制音符的持续时间须根据乐曲的速度及每个音符的节拍数来确定因此,在想控制音符的音长,就必须知道乐曲的速度和每个音符所对应的节拍数,在这个设计中所演奏的乐曲的最短的音符为四分音符,如果将全音符的持续时间设为1s的话,那么一拍所应该持续的时间为0.25秒,则只需要再提供一个4HZ的时钟频率即可产生四分音符的时长。
要想让系统知道现在应该演奏哪个音符,而这个音符持续的时间应该是多少,就必须编写乐曲文件,在乐曲文件中音符是按地址存放的,当系统工作时就按4Hz的频率依次读取简谱,当系统读到某个音符的简谱时就对应发这个音符的音调,持续时间为0.25秒,而如果在曲谱文件中这个音符为三拍音长,那又该如何控制呢?其实只要将该音符连续书写三遍,这时系统读乐曲文件的时候就会连续读到三次,也就会发三个0.25秒的音长,这时我们听上去就会持续了三拍的时间,通过这样一个简单的操作就可以控制音乐的音长了三.源程序1、编码器library ieee;use ieee.std_logic_1164.all;entity bianma is port( din:in std_logic_vector(3 downto 0); view:out std_logic_vector(2 downto 0); dout:out std_logic_vector(10 downto 0)); end bianma;architecture made_bianma of bianma is begin process(din) begin case din is --gao_yin --when ""=>dout<="11100000011";--1795 --when ""=>dout<="11011100100";--1764 --when ""=>dout<="11011000001";--1729 when "1100"=>dout<="11010011010";view<="110";--1690--12 when "1011"=>dout<="11010000101";view<="110";--1669--11 when "1010"=>dout<="11001010110";view<="110";--1622--10 when "1001"=>dout<="11000100010";view<="110";--1570--9 --zhong_yin --when ""=>dout<="11000000110";--1542 --when ""=>dout<="10111001000";--1480 --when ""=>dout<="10110000010";--1410 when "1000"=>dout<="10100110100";view<="101";--1332--8 when "0111"=>dout<="10100001010";view<="101";--1290--7 when "0110"=>dout<="10010101101";view<="101";--1197--6 when "0101"=>dout<="10001000100";view<="101";--1092--5 --di_yin --when ""=>dout<="10000001100";--1036 --when ""=>dout<="01110010000";--912 --when ""=>dout<="01100001101";--781 when "0100"=>dout<="01001101000";view<="011";--616--4 when "0011"=>dout<="01000010000";view<="011";--528--3 when "0010"=>dout<="00101011001";view<="011";--345--2 when "0001"=>dout<="00010001001";view<="011";--137--1 when others => dout<="11111111111"; --2047 end case; end process;end made_bianma;2、三选一library ieee;use ieee.std_logic_1164.all;entity change is port( din1,din2,din3,din4:in std_logic_vector(3 downto 0); cs:in std_logic_vector(1 downto 0); dout:out std_logic_vector(3 downto 0)); end change;architecture made_change of change is begin process(cs) begin case cs is when "00" =>dout<=din1; when "01" =>dout<=din2; when "10" =>dout<=din3; when "11" =>dout<=din4; when others =>dout<=din1; end case; end process;end made_change; 3、分频器library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity fenpin is port( din: in std_logic_vector(10 downto 0); clk: in std_logic; dout: out std_logic); end fenpin; architecture made of fenpin is signal temp:std_logic_vector(10 downto 0); begin process(din,clk) begin if(clkevent and clk=1)then if(temp=2047)then temp<=din; else temp<=temp+1; end if; end if; end process; dout<=1 when temp=2046 else 0; end made; 4、音乐模块1library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity made_music isport( clk_2hz:in std_logic; dout:out std_logic_vector(3 downto 0));end made_music;architecture make_music of made_music issignal temp:std_logic_vector(5 downto 0);begin process(clk_2hz) begin if(clk_2hzevent and clk_2hz=1) then if(temp=48) then temp<="000000"; else temp<=temp+1; end if; end if; end process; process(temp) begin case temp is when "000000" =>dout<="0001"; --1 when "000001" =>dout<="0001"; --1 when "000010" =>dout<="0011"; --3 when "000011" =>dout<="0011"; --3 when "000100" =>dout<="0010"; --2 when "000101" =>dout<="0010"; --2 when "000110" =>dout<="0100"; --4 when "000111" =>dout<="0100"; --4 when "001000" =>dout<="0101"; --5 when "001001" =>dout<="0101"; --5 when "001010" =>dout<="0111"; --7 when "001011" =>dout<="0111"; --7 when "001100" =>dout<="0110"; --6 when "001101" =>dout<="0110"; --6 when "001110" =>dout<="1000"; --8 when "001111" =>dout<="1000"; --8 when "010000" =>dout<="1001"; --9 when "010001" =>dout<="1001"; --9 when "010010" =>dout<="1011"; --11 when "010011" =>dout<="1011"; --11 when "010100" =>dout<="1100"; --12 when "010101" =>dout<="1100"; --12 when "010110" =>dout<="1011"; --11 when "010111" =>dout<="1011"; --11 when "011000" =>dout<="1010"; --10 when "011001" =>dout<="1010"; --10 when "011010" =>dout<="0101"; --5 when "011011" =>dout<="0101"; --5 when "011100" =>dout<="1000"; --8 when "011101" =>dout<="1000"; --8 when "011110" =>dout<="0110"; --6 when "011111" =>dout<="0110"; --6 when "100000" =>dout<="0111"; --7 when "100001" =>dout<="0111"; --7 when "100010" =>dout<="0100"; --4 when "100011" =>dout<="0100"; --4 when "100100" =>dout<="0011"; --3 when "100101" =>dout<="0011"; --3 when "100110" =>dout<="0001"; --1 when "100111" =>dout<="0001"; --1 when "101000" =>dout<="0010"; --2 when "101001" =>dout<="0010"; --2 when "101010" =>dout<="0001"; --1 when "101011" =>dout<="0001"; --1 when others=>dout<="0000"; --0 end case; end process;end make_music; 音乐模块2 library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity made_music1 isport( clk_2hz:in std_logic; dout:out std_logic_vector(3 downto 0));end made_music1;architecture make_music of made_music1 issignal temp:std_logic_vector(6 downto 0);begin process(clk_2hz) begin if(clk_2hzevent and clk_2hz=1) then if(temp=72) then temp<="0000000"; else temp<=temp+1; end if; end if; end process; process(temp) begin case temp is when "0000000" =>dout<="0001"; --1 when "0000001" =>dout<="0001"; --1 when "0000010" =>dout<="0010"; --2 when "0000011" =>dout<="0010"; --2 when "0000100" =>dout<="0011"; --3 when "0000101" =>dout<="0011"; --3 when "0000110" =>dout<="0011"; --3 when "0000111" =>dout<="0011"; --3 when "0001000" =>dout<="0010"; --2 when "0001001" =>dout<="0010"; --2 when "0001010" =>dout<="0001"; --1 when "0001011" =>dout<="0001"; --1 when "0001100" =>dout<="0010"; --2 when "0001101" =>dout<="0010"; --2 when "0001110" =>dout<="0011"; --3 when "0001111" =>dout<="0011"; --3 when "0010000" =>dout<="0100"; --4 when "0010001" =>dout<="0100"; --4 when "0010010" =>dout<="0100"; --4 when "0010011" =>dout<="0100"; --4 when "0010100" =>dout<="0011"; --3 when "0010101" =>dout<="0011"; --3 when "0010110" =>dout<="0010"; --2 when "0010111" =>dout<="0010"; --2 when "0011000" =>dout<="0101"; --5 when "0011001" =>dout<="0101"; --5 when "0011010" =>dout<="0110"; --6 when "0011011" =>dout<="0110"; --6 when "0011100" =>dout<="0111"; --7 when "0011101" =>dout<="0111"; --7 when "0011110" =>dout<="0111"; --7 when "0011111" =>dout<="0111"; --7 when "0100000" =>dout<="0101"; --5 when "0100001" =>dout<="0101"; --5 when "0100010" =>dout<="0110"; --6 when "0100011" =>dout<="0110"; --6 when "0100100" =>dout<="0110"; --6 when "0100101" =>dout<="0110"; --6 when "0100110" =>dout<="0111"; --7 when "0100111" =>dout<="0111"; --7 when "0101000" =>dout<="1000"; --8 when "0101001" =>dout<="1000"; --8 when "0101010" =>dout<="1000"; --8 when "0101011" =>dout<="1000"; --8 when "0101100" =>dout<="0111"; --7 when "0101101" =>dout<="0111"; --7 when "0101110" =>dout<="0110"; --6 when "0101111" =>dout<="0110"; --6 when "0110000" =>dout<="1001"; --9 when "0110001" =>dout<="1001"; --9 when "0110010" =>dout<="1010"; --10 when "0110011" =>dout<="1010"; --10 when "0110100" =>dout<="1011"; --11 when "0110101" =>dout<="1011"; --11 when "0110110" =>dout<="1011"; --11 when "0110111" =>dout<="1011"; --11 when "0111000" =>dout<="1010"; --10 when "0111001" =>dout<="1010"; --10 when "0111010" =>dout<="1001"; --9 when "0111011" =>dout<="1001"; --9 when "0111100" =>dout<="1010"; --10 when "0111101" =>dout<="1010"; --10 when "0111110" =>dout<="1011"; --11 when "0111111" =>dout<="1011"; --11 when "1000000" =>dout<="1100"; --12 when "1000001" =>dout<="1100"; --12 when "1000010" =>dout<="1100"; --12 when "1000011" =>dout<="1100"; --12 when "1000100" =>dout<="1011"; --11 when "1000101" =>dout<="1011"; --11 when "1000110" =>dout<="1010"; --10 when "1000111" =>dout<="1010"; --10 when others=>dout<="0000"; --0 end case; end process;end make_music;音乐模块3library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity made_music2 isport( clk_2hz:in std_logic; dout:out std_logic_vector(3 downto 0));end made_music2;architecture make_music of made_music2 issignal temp:std_logic_vector(6 downto 0);begin process(clk_2hz) begin if(clk_2hzevent and clk_2hz=1) then if(temp=45) then temp<="0000000"; else temp<=temp+1; end if; end if; end process; process(temp) begin case temp is when "0000000" =>dout<="0001"; --1 when "0000001" =>dout<="0001"; --1 when "0000010" =>dout<="0010"; --2 when "0000011" =>dout<="0010"; --2 when "0000100" =>dout<="0011"; --3 when "0000101" =>dout<="0011"; --3 when "0000110" =>dout<="0100"; --4 when "0000111" =>dout<="0100"; --4 when "0001000" =>dout<="0101"; --5 when "0001001" =>dout<="0101"; --5 when "0001010" =>dout<="0110"; --6 when "0001011" =>dout<="0110"; --6 when "0001100" =>dout<="0111"; --7 when "0001101" =>dout<="0111"; --7 when "0001110" =>dout<="1000"; --8 when "0001111" =>dout<="1000"; --8 when "0010000" =>dout<="1001"; --9 when "0010001" =>dout<="1001"; --9 when "0010010" =>dout<="1010"; --10 when "0010011" =>dout<="1010"; --10 when "0010100" =>dout<="1011"; --11 when "0010101" =>dout<="1011"; --11 when "0010110" =>dout<="1100"; --12 when "0010111" =>dout<="1100"; --12 when "0011000" =>dout<="1011"; --11 when "0011001" =>dout<="1011"; --11 when "0011010" =>dout<="1010"; --10 when "0011011" =>dout<="1010"; --10 when "0011100" =>dout<="1001"; --9 when "0011101" =>dout<="1001"; --9 when "0011110" =>dout<="1000"; --8 when "0011111" =>dout<="1000"; --8 when "0100000" =>dout<="0111"; --7 when "0100001" =>dout<="0111"; --7 when "0100010" =>dout<="0110"; --6 when "0100011" =>dout<="0110"; --6 when "0100100" =>dout<="0101"; --5 when "0100101" =>dout<="0101"; --5 when "0100110" =>dout<="0100"; --4 when "0100111" =>dout<="0100"; --4 when "0101000" =>dout<="0011"; --3 when "0101001" =>dout<="0011"; --3 when "0101010" =>dout<="0010"; --2 when "0101011" =>dout<="0010"; --2 when "0101100" =>dout<="0001"; --1 when "0101101" =>dout<="0001"; --1 when others=>dout<="0000"; --0 end case; end process;end make_music; 4、 总原理图五、实验目的1. 熟练掌握VHDL 语言和QUARTUS II 软件的使用;2. 理解状态机的工作原理和设计方法;3. 掌握利用EDA 工具进行自顶向下的电子系统设计方法六、实验步骤1.将实验系统上RS232接口与计算机串行口相连。
2.用VHDL将源程序输入QUARTUS II软件中3.编译程序并进行引脚分配,最后将程序下载到器件中去七、收获和体会:通过本次EDA课设,我学会了VHDL语言的一些基本用法,应用了原来不会或者不熟练的句型,如if句,也学会了一些基本功能的实现方法,如分频,状态控制等等,从另外一个角度重新审视了这个学期完全从硬件角度出发的电路设计,明白了软硬件之间的交互通过这次实验,对系统框图的设计有了一定的了解懂得了系统的前期设计对于后续的编程和调试的重要性本次实验采用了自下而上的设计方法,根据系统对硬件的要求,分化模块,利用模块实现功能,最后进行仿真和调试虽然这次实验遇到的问题不少,但是在胡辉老师以及同学的帮助下,我都顺利地解决了,并为将来的实践积累了宝贵的经验和教训具体的经验和教训有:1模块化设计有利于提高硬件设计的效率2逻辑正确和仿真真确并不代表着实际实验的正确,通常情况下,要适当地调整逻辑以适应硬件要特别注意仿真时出现的毛刺和偏差,到底是由于仿真设置不合理还是仿真结果确实有问题3从简到难,逐步深入,先打出程序的框架,实现基本功能,然后再逐步细化4学会经常和老师、同学交流,以便及时发现自己在实验中的纰漏和不足,促进进步。
这次实验本人态度认真,积极向其他同学求教并在此过程中得到很多收获,能够进一步了解和使用一门与硬件直接打交道的基本语言对我们将来的学习和工作都会十分有益实验的顺利完成,与老师的热心指导是分不开的,最后十分感谢胡辉老师的认真负责的工作,让我受益匪浅!八、参考文献《EDA技术与实验》 机械工业出版社 李国洪、胡辉、沈明山《EDA技术实验与课程设计》 清华大学出版社 曹新燕、周凤臣、聂春燕《EDA技术综合应用实例与分析》 西安电子科技大学出版社 谭会生、翟遂春 评 语 课程设计成绩: 指导教师: 日期: 年 月 日 24。




