简易乐曲演奏器的设计说明_第1页
简易乐曲演奏器的设计说明_第2页
简易乐曲演奏器的设计说明_第3页
简易乐曲演奏器的设计说明_第4页
简易乐曲演奏器的设计说明_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、. . . . 1 引言VHDL是一种硬件描述语言,它可以对电子电路和系统的行为进行描述,基于这种描述,结合相关的软件工具,可以得到所期望的实际电路与系统。使用VHDL语言描述的电路,可以进行综合和仿真。然而,值得注意的是,尽管所有VHDL代码都是可仿真的,但并不是所有代码都能综合。VHDL被广泛使用的基本原因在于它是一种标准语言,是与工具和工艺无关的,从而可以方便地进行移植和重用。VHDL两个最直接的应用领域是可编程逻辑器件(PLD)和专用集成电路(ASIC),其中可编程逻辑器件包括复杂可编程逻辑器件(CPLD)和现场可编程门阵列(FPGA)。关于VHDL最后要说明的是:与常规的顺序执行的计

2、算机程序不同,VHDL从根本上讲是并发执行的。在VHDL中,只有在进程(PROCESS)、函数(FUNCTION)和过程(PROCEDURE)部的语句才是顺序执行的。本课程设计主要是基于VHDL文本输入法设计乐曲演奏电路,该系统基于计算机中时钟分频器的原理,采用自顶向下的设计方法来实现,通过按键输入来控制音响或者自动演奏已存入的歌曲。系统实现是用硬件描述语言VHDL按模块化方式进行设计,然后进行编程、时序仿真、电路功能验证,奏出美妙的乐曲(当然由于条件限制,暂不进行功能验证,只进行编程和时序仿真)。该设计最重要的一点就是通过按键控制不同的音调发生,每一个音调对应不同的频率,从而输出对应频率的声

3、音。我们知道,与利用单片机来实现乐曲演奏相比,以纯硬件完成乐曲演奏电路的逻辑要复杂得多,如果不借助于功能强大的EDA工具与硬件描述语言,仅凭传统的数字逻辑技术,即使最简单的演奏电路也难以实现。2 整体功能介绍2.1准备知识在本次设计中采用了铃声欢迎你作为要播放的乐曲,它的旋律如下: 3 5 3 2 3 2 3 3 2 6 1 3 2 2 2 1 6 1 2 3 5 2 3 6 5 6 2 1 12 1 6 1 2 3 5 2 3 6 5 5 3 2 3 2 1 5 6 2 5 3 3 2 3 (加粗表示低音,其他为中音) 根据声乐知识,组成乐曲的每个音符的发音频率值与其持续的时间是乐曲能连续演

4、奏所需的两个基本要素,获取这两个要素所对应的数值以与通过纯硬件的手段来利用这些数值实现所希望乐曲的演奏效果是本实验的关键。表2-1为简谱中音名与频率的对应关系。音名频率(Hz)音名频率(Hz)音名频率(Hz)低音1261.63中音1523.25高音11046.50低音2293.67中音2587.33高音21174.66低音3329.63中音3659.25高音31381.51低音4349.23中音4698.46高音41396.92低音5391.99中音5783.99高音51567.98低音6440中音6880高音61760低音7439.88中音7987.76高音71975.52表2-1 音名和频

5、率的关系1.基准频率的选取各音名所对应的频率可由一频率较高的基准频率进行整数分频得到,所以实际产生各音名频率为近似的整数值。这是由于音阶频率多为非整数,而分频系数又不能为小数,故必须将得到的分频系数四舍五入取整,若基准频率过低,则由于分频系数过小,四舍五入取整后的误差较大,若基准频率过高,虽然误码差较小,但分频结构将变大,实际的设计应综合考虑两方面的因素,在尽量减小频率差的前提下取舍合适的基准频率。本次设计选择12MHz作为基准频率。2. 分频系数A、公用二进制的计数容量N与初始值的选取D(1)分频系数的选取 首先将12MHz的基准频率进行12分频,得到1MHz的基准频率,分频系数A1MHz音

6、名频率,此分频系数可由计数器实现。但若不加处理语句,其分频后的信号将不是对称方波。而占空比很小的方波很难使扬声器有效地发出声响。为得到对称方波,可将分频系数A分解为:分频系数A=分频系数n×2。即先进行分频系数n的分频,得到不对称方波,然后再2分频得到对称方波。(2)公用二进制的计数容量N的选取n分频可由n进制计数器实现。n进制计数器可用复位法或置位法实现,由于加载初始值d的置位法可有效地减少设计所占用的可编程逻辑器件资源,因此,此次设计采用置位法。低音1的分频数n为最大,其值为1275,应取公用二进制计数器的计数容量N大与“最大分频系数n”,故本次设计的公用二进制计数器应该设计为十

7、一位二进制加法计数器,其计数最大容量为2048,计数的最大值N为2047,可满足本次设计中所有音名对音频系数的要求。3. 初始值的选取D初始值D = 计数最大值N - 分频系数n此次设计中应用的各音名对应的分频系数值与初始值如表2-2所示:由于对应的频率点都有小数部分,在分频时不需花大量时间去产生分频电路,只要大概频率点在此围即可,本实验采用频率点与音符与音谱对应定义如表2-2所示。音符对应频率点对应音谱区别高中低音5771506911601109111211962131289314133141514095161479617154171表2-2 音符和音谱等关系该演奏电路的最小节拍为1拍,将一

8、拍的时长定为0.25s,则只需要再提供一个4Hz的时钟频率即可产生一拍的时长。为了能达到演奏时能循环进行,则需设置一个时长计数器,当乐曲演奏完时,保证能自动从头开始演奏。因采用4HZ的频率,故将音谱修改为3 3 5 5 3 3 2 2 3 3 2 2 3 3 3 3 3 3 2 2 6 6 1 1 3 3 2 2 2 2 2 2 1 1 6 6 1 1 2 2 3 3 5 5 2 2 3 3 6 6 5 5 6 6 2 2 1 1 1 1 2 2 1 1 6 6 1 1 2 2 3 3 5 5 2 2 3 3 6 6 5 5 5 5 3 3 3 3 3 3 3 3 2 2 3 3 2 2 1

9、1 5 5 6 6 2 2 2 2 5 5 3 3 3 3 3 3 2 2 2 2 3 3 3 3 2.2 乐曲演奏电路的结构示意本设计由5个模块组成,顶层结构所包含的模块分别为分频器(fenpin)模块、音调发生器(ydfsq)模块、音调编码器(ydbmq)模块、手动自动选择(bmux)模块与数控分频器(skfpq)模块。如图2-3所示分频器手动/自动音调发生器数控分频器音调编码器图 2-3 电路结构示意图2.3整体功能描述演奏时可以通过按键选择是手动演奏还是自动演奏,自动演奏则是演奏已存入的固定乐曲,而且自动播放能重复播放;手动演奏是通过按键进行简易乐曲的演奏;进行手动演奏和自动演奏时,数

10、码管上要同时能显示出演奏乐曲的乐谱。3 各模块与顶层介绍与仿真3.1分频器3.1.1功能描述根据设计要求,需要用一个时钟信号对音调发生模块和音调编码模块进行控制,该模块是将12MHZ的频率分成4HZ,以便用于产生音调发生器的CLK。源程序如下:library ieee;use ieee.std_logic_1164.all;entity fpq is port(clk:in std_logic;out1:buffer std_logic);end fpq;architecture bhv of fpq isbeginprocess(clk)variable count:integer rang

11、e 0 to 1500000;begin If clk'event and clk='1' then count:=count+1;If count=1500000 then out1<=not out1;count:=0;end if;end if;end process;end bhv;3.1.2仿真图图3-1 分频器仿真图3.2音调发生器3.2.1功能描述在此模块中设置了一个计数器(计数最大值为200),这个计数器的计数频率选为4Hz,即每一计数值的停留时间为0.25s,恰好为当全音符设为1s时,四四拍的4分音符的持续时间。例如,ydfsq在以下的VHDL逻

12、辑描述中,“欢迎你”乐曲的第一个音符为“3”,此音在逻辑中停留了2个时钟节拍,即为0.5s时间,相应地所对应“3”音符分频预置数为1289在skfpq的输入端停留了0.5s。随着计数器按4Hz的时钟频率做加法计数时,乐谱逐次被选取,乐曲就开始自然连续而且循环地演奏起来。源程序如下:library ieee;use ieee.std_logic_1164.all; -库的声明entity ydfsq isport(clk:in std_logic;toneindex:out integer range 0 to 15);end;architecture bhv of ydfsq issignal

13、 counter:integer range 0 to 200; -读取音符谱中的音符beginprocess(clk,counter)beginif counter=63 thencounter<=0;elsif clk'event and clk='1' thencounter<=counter+1;end if;end process;process(counter)begincase counter is when 108|109=>toneindex<=5;when 20|21|34|35|52|53|64|65=>toneind

14、ex<=6;when 22|23|32|33|36|37|56 to 59|62|63|66|67|98|99=>toneindex<=8;when6|7|10|11|18|19|26 to 31|38|39|44|45|54|55|60|61|68|69|74|75|92|93|96|97|104to 107|116 to 119=>toneindex<=9;When 0|1|4|5|8|9|12 to 17|24|25|40|41|46|47|70|71|76|77|84 to 91|94|95|110 to 115|120 to 123=>tonein

15、dex<=10;When 2|3|42|43|50|51|72|73|80 to 83|100|101|108|109=>toneindex<=12;When 78|79|102|103=>toneindex<=13;When others=>null;end case;end process;end;3.2.2仿真图图3-2 音调发生器仿真图通过仿真图可以清楚的看到,时钟clk由0开始计数,每计一次数输出toneindex的值随之发生一定的变化,只不过根据乐谱的不同,输出的变化也不尽一样。然后把输出toneindex输入到音调编码器模块,进行下一步编码工作

16、。于是,由仿真图印证了ydfsq模块逐次选取音符的功能。3.3手动自动选择器3.3.1功能描述根据设计的要求,该简易乐曲演奏器能实现手动或自动演奏乐曲的功能。于是,可通过一个按键cs来进行自动与手动的选择,当cs按下时,乐曲自动演奏,其他情况下均为手动演奏乐曲,即可以通过按下其他的按键来控制不同的音符。与此同时,还需要一个复位信号rst来控制该演奏器是否工作,当rst为1时,停止演奏,为0时可以演奏。以上提到的手动与自动的选择只能在rst为0时有效。源程序如下:library ieee;use ieee.std_logic_1164.all;entity bmux isport(d1,d2:i

17、n integer range 0 to 15;cs,rst:in std_logic;q:out integer range 0 to 15); end;architecture bhv of bmux isbegin process(cs,rst)beginif rst='1' then q<=0;elsecase cs iswhen '0'=>q<=d1; when '1'=>q<=d2; when others=>q<=d1;end case;end if;end process;end;3.3.

18、2仿真图图3-3 手动/自动选择器仿真图此仿真图中输入cs代表手动自动演奏的选择端,输入rst代表整体复位端,输入d1、d2分别代表手动和自动演奏的音符,q为输出端,由此仿真图可清楚的看到当rst=1时,不论选择的是手动还是自动,输出都为零,达到了整体复位的功能;当rst=0且cs=1时,自动演奏乐曲,因为q与d2的值一样;当rst=0且cs=0时,手动演奏乐曲,因为这时的q与d1的值一样,从而也达到了演奏方式选择的功能3.4音调编码器3.4.1功能描述该编码模块的作用为将输入的音符数据翻译为音乐产生模块的所需要的分频系数,并且显示音符的数字码型和高音阶,通过对照表2-2各音名对应的分频系数值

19、与初始值,根据输入得到初始值,从而得到分频系数以便进行分频,得到所需的频率。源程序如下:library ieee;use ieee.std_logic_1164.all;entity ydbmq isport(index:in integer range 0 to 15;code:out integer range 0 to 15;code1:out integer range 0 to 15;tone:out integer range 0 to 2047);end;architecture bhv of ydbmq isbeginprocess(index)begin case index

20、 is when 5=>tone<=771;code<=5;code1<=0;when 6=>tone<=911;code<=6;code1<=0; when 8=>tone<=1091;code<=1;code1<=1;when 9=>tone<=1196;code<=2;code1<=1;when 10=>tone<=1289;code<=3;code1<=1; when 11=>tone<=1331;code<=4;code1<=1;when 1

21、2=>tone<=1409;code<=5;code1<=1;when 13=>tone<=1479;code<=6;code1<=1;when 14=>tone<=1541;code<=7;code1<=1;when others=>NULL;end case;end process;end ;3.4.2仿真图图 3-4 音调编码器仿真图在此程序中index为音乐节拍产生模块输出的音符数据,经过翻译后将tone输出到数控分频模块为其提供分频系数的初始值,code为数码管显示的字符数,应用模式5,所以直接输出音符的二

22、进制值,code1为高音阶指示信号,当code1为是说明输出为高音阶的音符。通过仿真图可以清楚地看到结果。3.5数控分频器3.5.1功能描述该模块的clk端输入一个具有较高频率(本实验为12MHz)的信号,通过skfpq分频后由spkout输出。由于直接从数控分频器中出来的输出信号是脉宽极窄的脉冲信号,为了便于驱动喇叭,需另加一个D触发器均衡其占空比,也即作二分频处理。skfpq对clk输入信号的分频比由11位预置数tone10.0决定。spkout的输出频率将决定每一音符的音调,这样分频计数器的预置数tone10.0与spkout的输出频率就有了对应关系。源程序如下:library ieee

23、;use ieee.std_logic_1164.all;entity skfpq isport(clk:in std_logic;tone:in integer range 0 to 2047;spks:out std_logic);end;architecture bhv of skfpq issignal preclk:std_logic;signal fullspks:std_logic;begin process(clk)variable count4:integer range 0 to 15;begin preclk<='0'if count4=12 the

24、n -将基准频率进行12分频preclk<='1'count4:=0;elsif clk'event and clk='1' then count4:=count4+1;end if;end process;process(preclk,tone)variable count11:integer range 0 to 2047;begin if preclk'event and preclk='1' then -按分频系数进行分频 if count11=2047 thencount11:=tone;fullspks<=

25、'1' else count11:=count11+1;fullspks<='0' end if;end if;end process;process(fullspks)variable count2:std_logic;beginif fullspks'event and fullspks='1' thencount2:=not count2; if count2='1' then spks<='1' elsespks<='0' end if;end if;end pro

26、cess;end;3.5.2仿真图图 3-5 数控分频器仿真图在此仿真图中,输入clk是一个频率较大的时钟信号,输入tone代表着某个音符的分频初始值,输出spks则代表将输入clk先经过12次分频,再经过(预置数终值2048-tone)次分频,最终再进行二分频处理,而这个信号的频率就是我们需要演奏的音谱的频率,根据频率的不同,从而能通过喇叭听到不同的声音,实现音乐的播放。3.6系统顶层3.6.1源程序library ieee;use ieee.std_logic_1164.all;entity bfq isport(clk1:in std_logic;CS:in std_logic;RST:

27、in std_logic;D2:in integer range 0 to 15;oup1:out std_logic;oup2:out integer range 0 to 15;oup3:out integer range 0 to 15);end;architecture bhv of bfq issignal s1: integer range 0 to 15;signal s2: integer range 0 to 15;signal s3: integer range 0 to 2047;signal s4: std_logic;component fpqisport(clk:i

28、n std_logic;out1:out std_logic);end component;component ydfsq isport(clk:in std_logic;toneindex:out integer range 0 to 15);end component;component ydbmq isport(index:in integer range 0 to 15;code:out integer range 0 to 15;code1:out integer range 0 to 15;tone:out integer range 0 to 2047);end componen

29、t;component bmux isport(d1,d2:in integer range 0 to 15;cs,rst:in std_logic;q:out integer range 0 to 15);end component;component skfpq isport(clk:in std_logic;tone:in integer range 0 to 2047;spks:out std_logic);end component;beginu0:fpq port map(clk1,s4);u1: ydfsq port map(s4,s1);u2:ydbmq port map(s2

30、,oup2,oup3,s3);u3:bmux port map(s1,D2,CS,RST,s2);u4:skfpq port map(clk1,s3,oup1);end bhv;3.6.2仿真图图 3-6 顶层仿真图4 硬件调试结果输入程序并且编译无误,并且仿真无误后,便进行引脚锁定与程序下载,在进行引脚锁定时必须对照引脚锁定图进行锁定,采用模式5其引脚锁定图如图4-1所示:图 4-1模式5实验电路结构图根据需要,本设计采用模式5,这是因为数码管自带译码芯片,输出时只需输出数字的二进制数,因此不必直接输出数字的码型,这就方便了字符的输出。根据模式5上所对应的引脚号查表可以得出需要锁定的引脚。引

31、脚图如下图所示:图4-2 引脚锁定图cs键8 为自动手动选择键,当cs=1时为手动,否则为自动;clk1 锁定clock0的12Mhz;oup2锁定译码管8;oup3锁定译码管1;D2锁定键1到键4;oup1锁定扬声器。引脚锁定后执行programmer 下载程序至试验箱进行验证,当键8都没按下时,为手动选择模式,默认为循环播放存储的歌,当键8按下时,为手动模式,无论手动自动译码管都显示乐谱,故经验证本次设计完成的设计基本正确,但是基准时钟选取的不同演奏的效果不同。5总结1、本次简易乐曲演奏器的设计经过了整体分析、模块化分析、整体与模块的仿真分析这样三个步骤,硬件实现了整体复位、按键选择演奏方

32、式、循环演奏以与数码管显示乐谱的功能。2、在做数控分频器模块的仿真时一定要处理好时序问题。3、本次设计可以说达到了设计要求,但尚有需要改进的地方。随着乐谱的复杂程度加大,如果依然在音调发生器的程序过时钟计数来决定音符的输出,会加大编程的繁杂度,这时一个很好的解决办法就是把将要演奏的乐谱存放在人为开辟的存储空间里,这样只需要在相应地址中读出音符即可。通过本次课程设计,从实际应用方面深刻体会了VHDL设计的优势,通过强大的EDA工具和硬件描述语言使演奏电路很易实现。并且通过此次设计让我们把课本中的知识系统的联系起来,更加体会到模块式设计的方法所带来的方便和明了化。通过模块式的方法,可以将复杂的总程

33、序分成几个模块各自分工执行,独立工作互不干扰。然后通过原理图将各个模块直接相连,或者用元件例化的方式,用VHDL语言进行描述,达到了统一化管理各个模块的作用。通过查找资料,与同学交流增强了我们自主学习的能力;了解到了声音音谱的发生规律,信号的频率与声音的关系,并且通过对基准频率的分频,来生成不同的声谱。从设计方面得知,在进行设计时,应首先对各方面的资料进行综合,在基本原理的围进行模块式的分解和综合,最后达到设计的需求。这次设计使我对quartus的运用更加灵活,熟悉了对该软件从工程建立到程序下载执行各个步骤的操作,对以前学习上的不足得到了补充。总之,这次设计让我们学到了很多知识,为我们以后的学

34、习奠定了基础。参考文献1.Voknei A.Pedroni.VHDL数字电路设计教程.电子工业,2008.52.松,黄继业.EDA技术实用教程(第二版).科学,2005.23.焦素敏.EDA应用技术.清华大学,2002.44.徐向民.数字系统设计与VHDL实践.机械工业,2007.105.江海.EDA技术课程设计.华中科技大学,2009.5附录分频器library ieee;use ieee.std_logic_1164.all;entity fpq is pPort(clk:in std_logic;out1:buffer std_logic);end fpq;architecture bh

35、v of fpq isbeginprocess(clk)variable count:integer range 0 to 1500000;begin If clk'event and clk='1' then count:=count+1;If count=1500000 then out1<=not out1;count:=0;end if;end if;end process;end bhv;音调编码器(欢迎你)library ieee;use ieee.std_logic_1164.all; -库的声明entity ydfsq isport(clk:in

36、std_logic;toneindex:out integer range 0 to 15);end;architecture bhv of ydfsq issignal counter:integer range 0 to 200; -读取音符谱中的音符beginprocess(clk,counter)beginif counter=63 thencounter<=0; elsif clk'event and clk='1' thencounter<=counter+1;end if;end process;process(counter)begincas

37、e counter is when 108|109=>toneindex<=5;when 20|21|34|35|52|53|64|65=>toneindex<=6;when 22|23|32|33|36|37|56 to 59|62|63|66|67|98|99=>toneindex<=8;when 6|7|10|11|18|19|26 to 31|38|39|44|45|54|55|60|61|68|69|74|75|92|93|96|97|104 to 107|116 to 119=>toneindex<=9;when 0|1|4|5|8|

38、9|12 to 17|24|25|40|41|46|47|70|71|76|77|84 to 91|94|95|110 to 115|120 to 123=>toneindex<=10;when 2|3|42|43|50|51|72|73|80 to 83|100|101|108|109=>toneindex<=12;when 78|79|102|103=>toneindex<=13;when others=>null;end case;end process;end;音调编码器library ieee;use ieee.std_logic_1164.

39、all;entity ydbmq isport(index:in integer range 0 to 15;code:out integer range 0 to 15;code1:out integer range 0 to 15;tone:out integer range 0 to 2047);end;architecture bhv of ydbmq isbeginprocess(index)begin -为个音符赋初始值以便进行分频case index is when 5=>tone<=771;code<=5;code1<=0;when 6=>tone

40、<=911;code<=6;code1<=0; when 8=>tone<=1091;code<=1;code1<=1;when 9=>tone<=1196;code<=2;code1<=1;when 10=>tone<=1289;code<=3;code1<=1; when 11=>tone<=1331;code<=4;code1<=1;when 12=>tone<=1409;code<=5;code1<=1;when 13=>tone<=14

41、79;code<=6;code1<=1;when 14=>tone<=1541;code<=7;code1<=1;when others=>NULL;end case;end process;end ;自动/手动library ieee;use ieee.std_logic_1164.all;entity bmux isport(d1,d2:in integer range 0 to 15;cs,rst:in std_logic;q:out integer range 0 to 15); end;architecture bhv of bmux isb

42、egin process(cs,rst)beginif rst='1' then -复位时输出为0 q<=0;elsecase cs iswhen '0'=>q<=d1; -选择手动输入when '1'=>q<=d2; -选择自动演奏when others=>q<=d1;end case;end if;end process;end;数控分频器library ieee;use ieee.std_logic_1164.all;entity skfpq isport(clk:in std_logic;tone

43、:in integer range 0 to 2047;spks:out std_logic);end;architecture bhv of skfpq issignal preclk:std_logic;signal fullspks:std_logic;begin process(clk)variable count4:integer range 0 to 15;begin preclk<='0'if count4=12 then -将基准频率进行12分频preclk<='1'count4:=0;elsif clk'event and clk='1' then count4:=count4+1;end if;end process;process(preclk,tone)variable count11:integer range 0 to 2047;begin if preclk'event and preclk='1' then -按分频系数进行分频

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论