基于FPGA的电子琴设计.docx
- 文档编号:9254982
- 上传时间:2023-05-17
- 格式:DOCX
- 页数:19
- 大小:64.30KB
基于FPGA的电子琴设计.docx
《基于FPGA的电子琴设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的电子琴设计.docx(19页珍藏版)》请在冰点文库上搜索。
基于FPGA的电子琴设计
基于FPGA的电子琴设计
摘要:
系统应用FPGA技术,通过VHDL编程,在CPLD上实现。
电子琴的基本原理是产生各个音符对应的频率,将频率放大后驱动喇叭发出音响。
该电子琴包括手动弹奏与自动演奏两种功能,其中手动弹奏时还可录音回放。
文中叙述了电子琴的设计原理和分块实现的方法,详细介绍各模块的设计及模块之间的连接组合方法,还包括电子琴的使用说明。
关键字:
音符频率自动演奏录音回放
Abstract
ThesystemisanapplicationofFPGAusingVHDLonaCPLDchip.Thebasicprincipleofavibraphoneistogeneratethefrequenciesofthetones.Thenthefrequenciesareamplifiedtodrivethespeakertomakesounds.Thetwofunctionsofthisvibraphonearehandplayingandautomaticplaying.Whilehandplaying,whatwasplayedcanberecordedandthenrepeated.Thedesigningwillbediscussedinthefollowingpaper,designoneachmoduleandcombinationofthemodulesaregivenindetails.Anoperationguideofthisvibraphoneisalsoincluded.
Keywords:
ToneFrequencyAutomaticplayingrecord&repeat
目录
第一章系统设计………………………………………………3
第二章单元电路设计…………………………………………3
2.1音频发生器的设计…………………………………3
2.2存储器模块的设计…………………………………4
2.3采样速率发生器的设计………………………………4
2.4键盘模块的设计……………………………………4
2.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.63=122310次分频,则得到的是261.6302Hz,可见,频率更加准确,音响效果更好。
通过实际测试,也证明了这一现象。
程序设计:
8个分频器程序基本相同,只是各自分频系数不同,见表2.1。
音符
C(中央)
D
E
F
G
A
B
C(高音)
(简谱)
1
2
3
4
5
6
7
1
频率(Hz)
261.63
293.66
329.63
349.23
392.00
440.00
493.88
523.25
对32MHz晶振的分频数
122310
108969
97078
91630
81633
72727
64793
61156
表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的程序仿真图:
其中,片选信号cs=1时有效,RAM记录musicin输入的信息,并可通过musicout监听,当auto=1时,由musicout输出记录的信息,当ROM的片选cs0=1时,RAM被挂起,输出为高阻。
clk接采样速率信号。
图2.1RAM仿真图
2.3采样速率发生器的设计
采样速率发生器是一个产生8Hz频率的分频器,对32MHz晶振的分频系数为4000000。
用于驱动RAM和ROM地址指针的偏移。
将其设计成可控分频器,则可调节播放速度以及改变录音速度。
程序见附录。
2.4键盘模块的设计
键盘模块用来演奏及控制电子琴的工作模式,演奏部分其实是与音频发生器相结合的,在音频发生器各个输出频率后分别加上一个两输入与门,键盘则连接到这些与门另一个输入脚上,即成为一个选通开关。
然后将这些与门的输出接一个或门,再输出到喇叭上。
键盘的控制按键部分实际是RAM和ROM的片选开关和状态控制开关。
同时有一个显示模块,将键入或播放的音符简谱显示出来(显示译码程序仿真图如图2.2)。
图2.2显示译码仿真图
2.5各模块的连接方法
如图2.3所示,为各模块连接方式。
其中,编程时键盘的输入是与RAM相结合的,通过RAM的控制开关,可使键盘的输入直接送到总线,也可使其既送到总线又送到RAM中,这使得对总线控制的实现更灵活方便,无需另加模块去控制总线。
图2.3电子琴电路图
三、软件设计
使用开发软件为XilinxISE4.2,编程语言为VHDL,仿真工具为ModelSimXilinxEdition5.3dXE,根据上述各单元电路的设计思路编程并调试,仿真(程序及仿真图见附录),最后作顶层程序,连接各单元电路,如上图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。
六、附录(程序清单)
音频发生器程序
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitypltn_keyis
Port(clk:
instd_logic;
kb:
instd_logic_vector(7downto0);
sound:
outstd_logic);
endpltn_key;
architectureBehavioralofpltn_keyis
signalsound_c,sound_d,sound_e,sound_f,sound_g,sound_a,sound_b,sound_c1:
std_logic;
begin
div_c:
process(clk)--frequencyofc
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=61155then
clk0:
='1';
elsifcount2=122310then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_c<=clk0;
endprocessdiv_c;
div_d:
process(clk)--frequencyofd
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=54484then
clk0:
='1';
elsifcount2=108969then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_d<=clk0;
endprocessdiv_d;
div_e:
process(clk)--frequencyofe
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=48539then
clk0:
='1';
elsifcount2=97078then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_e<=clk0;
endprocessdiv_e;
div_f:
process(clk)--frequencyoff
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=45815then
clk0:
='1';
elsifcount2=91630then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_f<=clk0;
endprocessdiv_f;
div_g:
process(clk)--frequencyofg
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=40816then
clk0:
='1';
elsifcount2=81663then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_g<=clk0;
endprocessdiv_g;
div_a:
process(clk)--frequencyofa
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=36364then
clk0:
='1';
elsifcount2=72727then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_a<=clk0;
endprocessdiv_a;
div_b:
process(clk)--frequencyofb
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=32396then
clk0:
='1';
elsifcount2=64793then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_b<=clk0;
endprocessdiv_b;
div_c1:
process(clk)--frequencyofc1
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclk'eventandclk='1'then
count2:
=count2+1;
ifcount2=30578then
clk0:
='1';
elsifcount2=61155then
count2:
=0;
clk0:
='0';
endif;
endif;
sound_c1<=clk0;
endprocessdiv_c1;
keyboard:
process(kb)―――键盘
variablesoundc,soundd,sounde,soundf,soundg,sounda,soundb,soundc1:
std_logic;
begin
ifkb(0)='1'thensoundc:
=sound_c;elsesoundc:
='0';endif;
ifkb
(1)='1'thensoundd:
=sound_d;elsesoundd:
='0';endif;
ifkb
(2)='1'thensounde:
=sound_e;elsesounde:
='0';endif;
ifkb(3)='1'thensoundf:
=sound_f;elsesoundf:
='0';endif;
ifkb(4)='1'thensoundg:
=sound_g;elsesoundg:
='0';endif;
ifkb(5)='1'thensounda:
=sound_a;elsesounda:
='0';endif;
ifkb(6)='1'thensoundb:
=sound_b;elsesoundb:
='0';endif;
ifkb(7)='1'thensoundc1:
=sound_c1;elsesoundc1:
='0';endif;
sound<=soundcorsounddorsoundeorsoundforsoundgorsoundaorsoundborsoundc1;
endprocesskeyboard;
endBehavioral;
RAM程序
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitymusic_ramis
Port(cs,cs0,auto,clk:
instd_logic;--auto='1':
read,'0'=write
musicin:
instd_logic_vector(7downto0);
musicout:
outstd_logic_vector(7downto0)
);
endmusic_ram;
architectureBehavioralofmusic_ramis
subtypewordisstd_logic_vector(7downto0);
TYPEmemoryISarray(64downto0)OFword;
signalmusram:
memory;
begin
process(clk,cs,cs0,auto,musicin)
variableaddr,ptr:
integerrange0to64;----------addressandpointer
begin
ifclk'eventandclk='1'then
ifcs0='1'thenmusicout<="ZZZZZZZZ";
elsifcs0='0'then
ifcs='1'then
ifauto='0'thenmusram(ptr)<=musicin;ptr:
=ptr+1;musicout<=musicin;
elsemusicout<=musram(addr);addr:
=addr+1;
endif;
elsemusicout<=musicin;
endif;
endif;
endif;
endprocess;
endBehavioral;
---"00000001"1
---"00000010"2
---"00000100"3
---"00001000"4
---"00010000"5
---"00100000"6
---"01000000"7
---"10000000"1
ROM程序
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitymusic_romis
Port(listen0,clk:
instd_logic;
--auto='1':
read,'0'=write
sing:
outstd_logic_vector(7downto0)
);
endmusic_rom;
architectureBehavioralofmusic_romis
subtypewordisstd_logic_vector(7downto0);
TYPEmemoryISarray(19downto0)OFword;--memory
constantmusrom:
memory:
=("00000001","00000010","00000100","00001000","00010000","00100000","01000000","10000000","01000000","00100000","00010000","00001000","00000100","00000010","00000001","00000010","00000100","00001000","00010000","00100000");
begin
process(clk)
variableaddr:
integerrange0to19;
begin
ifclk'eventandclk='1'then
iflisten0='1'then
sing<=musrom(addr);addr:
=addr+1;
elsesing<="ZZZZZZZZ";
endif;
endif;
endprocess;
endBehavioral;
采样速率发生器程序
entityplay_speedis
Port(clkin:
instd_logic;
speed:
outstd_logic);
endplay_speed;
architectureBehavioralofplay_speedis
begin
process(clkin)
variablecount2:
integer;
variableclk0:
std_logic;
begin
ifclkin'eventandclkin='1'then
count2:
=count2+1;
ifcount2=2000000then
clk0
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 FPGA 电子琴 设计
![提示](https://static.bingdoc.com/images/bang_tan.gif)