基于FPGA的电子琴设计.doc_第1页
基于FPGA的电子琴设计.doc_第2页
基于FPGA的电子琴设计.doc_第3页
基于FPGA的电子琴设计.doc_第4页
基于FPGA的电子琴设计.doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

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

文档简介

基于fpga的电子琴设计摘要:系统应用fpga技术,通过vhdl编程,在cpld上实现。电子琴的基本原理是产生各个音符对应的频率,将频率放大后驱动喇叭发出音响。该电子琴包括手动弹奏与自动演奏两种功能,其中手动弹奏时还可录音回放。文中叙述了电子琴的设计原理和分块实现的方法,详细介绍各模块的设计及模块之间的连接组合方法,还包括电子琴的使用说明。关键字:音符 频率 自动演奏 录音回放abstractthe system is an application of fpga using vhdl on a cpld chip. the basic principle of a vibraphone is to generate the frequencies of the tones. then the frequencies are amplified to drive the speaker to make sounds. the two functions of this vibraphone are hand playing and automatic playing. while hand playing, what was played can be recorded and then repeated. the designing will be discussed in the following paper, design on each module and combination of the modules are given in details. an operation guide of this vibraphone is also included.keywords: tone frequency automatic playing record & repeat目录第一章 系统设计3第二章 单元电路设计32.1音频发生器的设计 32.2存储器模块的设计 42.3采样速率发生器的设计42.4键盘模块的设计 42.5各模块的连接方法 5第三章 软件设计5第四章 系统测试6第五章 结论及参考文献6第六章 附录6一、 系统设计 根据系统的两大功能:手动弹奏与自动演奏,可将其分成音频发生模块,键盘控制模块和存储器模块三部分。系统框图如图1.1所示。音频发生模块由分频器组成,产生8个频率(还可扩展),对应8个音符(中央c,d,e,f,g,a,b和高音c),这些频率经放大后驱动喇叭,即可发出声音。键盘选择手动弹奏模式时,按下音符键后就选通相应的频率输出,可同时多个频率叠加输出,产生和弦效果,若同时打开录音开关,还可将所奏音乐记录下来,然后回放;选择自动演奏模式时,存储器里事先编写好的音符信息被依次取出,去选通各个频率输出,实现自动奏乐。音频发生模块存储器键盘控 制 线总 线图1.1 系统结构框图1.1方案比较:方案一:采用数字逻辑电路制作,用ic拼凑焊接实现。其特点是直接用现成的ic组合而成,简单方便,但本系统需用到许多分频器,使得使用的ic将相当多,因而体积庞大,连线复杂。方案二:采用单片机实现,通过软件编程,仿真后将程序用编程器写入到单片机芯片上,该方案成本低,稳定度较好,但外围电路较多,可别是录音时需要用到大容量的外部存储器,增加了编程难度,调试不够直观方便灵活。方案三:采用可编程逻辑器件(cpld)制作,将所有器件集成在一块芯片上,体积大大减小,用vhdl编程实现时更加方便,易于进行功能扩展,并可调试仿真,制作时间大大缩短。因此选用方案三。 二、 单元电路设计 2.1音频发生器的设计基本原理:音频发生器用于产生8个音符对应当频率,因此需使用8个不同分频数的分频器。表2.1给出了音符,频率,及分频数的对应关系。也可设计一个分频系数可预置的分频器,按键时送出分频系数来得到音频,但局限于每次只发出一个声音;若要同时发出几个声音,产生和弦效果,则必须使用多个分频器。分频器直接对32mhz晶振分频,可减少计算误差,得到较好的音质。例如:中央c的频率是161.63hz,如果先将32mhz频率降到1mhz,再进行1000000/261.63=3822(只取整数)次分频,得到的将是261.643hz,而直接进行32000000/261.63122310次分频,则得到的是261.6302hz,可见,频率更加准确,音响效果更好。通过实际测试,也证明了这一现象。程序设计:8个分频器程序基本相同,只是各自分频系数不同,见表2.1。音符c(中央)defgabc(高音)(简谱)12345671频率 (hz)261.63293.66329.63349.23392.00440.00493.88523.25对32mhz晶振的分频数122310108969970789163081633727276479361156表2.1 音符,频率及分频数对应关系2.2存储器模块的设计存储器模块由一个ram和一个rom组成,完成两个功能:录音回放和自动演奏。 ram用来实现录音回放功能,当键盘选择录音时,该ram被选通,并有由一个采样速率发生器控制,键盘输入的信息被依次记录到ram中,完成录音功能;选择回放时,同样由采样速率的脉冲控制,将ram中记录的信息依次取出,送至键盘与音频发生器之间的总线上,进入音频发生器即可驱动奏乐部分;录音回放模块的程序见附录。rom用来实现自动演奏功能,其中存放着事先编写好的曲子,选择自动演奏时,rom被选通,同样由采样速率发生器控制,依次取出rom中信息。由于采样速率是8hz, 一个音符的持续时间是0.125s。程序见附录。另外,存储器输出接在总线上,所以ram和rom的输出是三态的,当ram被选通时,rom被挂起,输出高阻,反之当rom被选通时,ram输出高阻。图2.1所示为ram的程序仿真图:其中,片选信号cs1时有效,ram记录musicin输入的信息,并可通过musicout监听,当auto1时,由musicout输出记录的信息,当rom的片选cs01时,ram被挂起,输出为高阻。clk接采样速率信号。图2.1 ram仿真图2.3采样速率发生器的设计采样速率发生器是一个产生8hz频率的分频器,对32mhz晶振的分频系数为4000000。用于驱动ram和rom地址指针的偏移。将其设计成可控分频器,则可调节播放速度以及改变录音速度。程序见附录。2.4键盘模块的设计键盘模块用来演奏及控制电子琴的工作模式,演奏部分其实是与音频发生器相结合的,在音频发生器各个输出频率后分别加上一个两输入与门,键盘则连接到这些与门另一个输入脚上,即成为一个选通开关。然后将这些与门的输出接一个或门,再输出到喇叭上。键盘的控制按键部分实际是ram和rom的片选开关和状态控制开关。同时有一个显示模块,将键入或播放的音符简谱显示出来(显示译码程序仿真图如图2.2)。图2.2 显示译码仿真图2.5各模块的连接方法如图2.3所示,为各模块连接方式。其中,编程时键盘的输入是与ram相结合的,通过ram的控制开关,可使键盘的输入直接送到总线,也可使其既送到总线又送到ram中,这使得对总线控制的实现更灵活方便,无需另加模块去控制总线。图2.3 电子琴电路图三、 软件设计 使用开发软件为xilinx ise 4.2,编程语言为vhdl,仿真工具为modelsim xilinx edition 5.3d xe,根据上述各单元电路的设计思路编程并调试,仿真(程序及仿真图见附录),最后作顶层程序,连接各单元电路,如上图2.3所示。四、 系统测试 系统测试在清华tpg_fpga实验箱上进行,使用其32mhz晶振,喇叭及一个led数码显示器。引脚锁定后将程序下载到目标芯片saprtan2系列的xc2s200-5pq208上,通过设置不同的工作模式,测试手动演奏,录音,回放和自动演奏各个功能,都能正常完成,且有较好音质。各模式之间的切换也正确无误。五、 结论系统通过仿真,测试,达到设计的基本要求,经过多次改进,实现了功能扩展,改善了音效,并且操作简单方便。电子琴使用方法:控制按键有三个:handplay,autoplay,rec_rep。handplay 置1时,以手动方式演奏,此时,若rec_rep为1,则演奏的内容将被记录,当rec_rep为0时,记录的内容被播放出来。autoplay置1时,电子琴演奏自动演奏,手动输入无效。参考文献:1. 黄正谨,徐坚,章小丽等.cpld系统设计技术入门与应用【m】. 北京:电子工业出版社.2002。2. 潘松,黄继业.eda 技术实用教程【m】.北京:科学出版社.2002。3. 赵俊超等.集成电路设计vhdl教程.【m】.北京.北京希望电子出版社.2002。六、 附录(程序清单)音频发生器程序10library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity pltn_key is port (clk: in std_logic; kb: in std_logic_vector(7 downto 0); sound: out std_logic);end pltn_key;architecture behavioral of pltn_key issignal sound_c,sound_d,sound_e,sound_f,sound_g,sound_a,sound_b,sound_c1 :std_logic;begindiv_c: process(clk) -frequency of c variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=61155 then clk0:=1;elsif count2=122310 then count2:=0; clk0:=0; end if;end if;sound_c=clk0; end process div_c;div_d: process(clk) -frequency of d variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=54484 then clk0:=1; elsif count2=108969 then count2:=0; clk0:=0; end if;end if;sound_d=clk0; end process div_d;div_e: process(clk) -frequency of e variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=48539 then clk0:=1; elsif count2=97078 then count2:=0; clk0:=0; end if;end if;sound_e=clk0; end process div_e;div_f: process(clk) - frequency of f variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=45815 then clk0:=1; elsif count2=91630 then count2:=0; clk0:=0; end if;end if;sound_f=clk0; end process div_f;div_g: process(clk) -frequency of g variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=40816 then clk0:=1; elsif count2=81663 then count2:=0; clk0:=0; end if;end if;sound_g=clk0; end process div_g;div_a: process(clk) -frequency of a variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=36364 then clk0:=1; elsif count2=72727 then count2:=0; clk0:=0; end if;end if;sound_a=clk0; end process div_a;div_b: process(clk) -frequency of b variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=32396 then clk0:=1; elsif count2=64793 then count2:=0; clk0:=0; end if;end if;sound_b=clk0; end process div_b;div_c1: process(clk) -frequency of c1 variable count2: integer;variable clk0: std_logic;beginif clkevent and clk=1 then count2:=count2+1; if count2=30578 then clk0:=1; elsif count2=61155 then count2:=0; clk0:=0; end if;end if;sound_c1=clk0; end process div_c1;keyboard: process(kb) 键盘variable soundc,soundd,sounde,soundf,soundg,sounda,soundb,soundc1:std_logic; begin if kb(0)=1 then soundc:=sound_c; else soundc:=0;end if; if kb(1)=1 then soundd:=sound_d; else soundd:=0;end if; if kb(2)=1 then sounde:=sound_e; else sounde:=0;end if; if kb(3)=1 then soundf:=sound_f; else soundf:=0;end if; if kb(4)=1 then soundg:=sound_g; else soundg:=0;end if; if kb(5)=1 then sounda:=sound_a; else sounda:=0;end if; if kb(6)=1 then soundb:=sound_b; else soundb:=0;end if; if kb(7)=1 then soundc1:=sound_c1; else soundc1:=0;end if;sound= soundc or soundd or sounde or soundf or soundg or sounda or soundb or soundc1; end process keyboard; end behavioral;ram程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity music_ram is port (cs,cs0,auto,clk :in std_logic; -auto=1:read ,0=writemusicin:in std_logic_vector(7 downto 0);musicout: out std_logic_vector(7 downto 0) );end music_ram;architecture behavioral of music_ram issubtype word is std_logic_vector(7 downto 0);type memory is array (64 downto 0) of word; signal musram : memory;begin process (clk,cs,cs0,auto,musicin)variable addr,ptr: integer range 0 to 64;-address and pointerbeginif clkevent and clk=1 then if cs0=1 then musicout=zzzzzzzz;elsif cs0=0 thenif cs=1 then if auto=0 then musram(ptr)=musicin;ptr:=ptr+1;musicout=musicin;else musicout=musram(addr);addr:=addr+1;end if;else musicout=musicin;end if;end if;end if;end process;end behavioral;-00000001 1-00000010 2-00000100 3-00001000 4-00010000 5-00100000 6-01000000 7-10000000 1rom程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity music_rom isport (listen0,clk :in std_logic;- auto=1:read ,0=write sing: out std_logic_vector(7 downto 0) );end music_rom;architecture behavioral of music_rom issubtype word is std_logic_vector(7 downto 0);type memory is array (19 downto 0) of word; -memoryconstant musrom:memory:=(00000001,00000010,00000100,00001000,00010000,00100000,01000000,10000000,01000000,00100000,00010000,00001000,00000100,00000010,00000001,00000010,00000100,00001000,00010000,0010000

温馨提示

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

评论

0/150

提交评论