基于vhdl八音符电子琴电路设计.docx
- 文档编号:25050369
- 上传时间:2023-06-04
- 格式:DOCX
- 页数:30
- 大小:400.23KB
基于vhdl八音符电子琴电路设计.docx
《基于vhdl八音符电子琴电路设计.docx》由会员分享,可在线阅读,更多相关《基于vhdl八音符电子琴电路设计.docx(30页珍藏版)》请在冰豆网上搜索。
基于vhdl八音符电子琴电路设计
一、设计任务与要求………………………………………1
二、总体框图……………………………………………2
三、选择器件……………………………………………5
四、功能模块……………………………………………6
1.Songer模块………………………………6
1.1NoteTabs模块………………………6
1.2ToneTaba模块………………………11
1.3Speakera模块………………………13
2.div模块……………………………………16
3.七段译码器模块……………………………18
五、总体设计电路图………………………………………21
1.顶层设计地电路原理图……………………21
2.顶层设计地仿真结果………………………23
3.电路地管脚图………………………………23
六、结束语………………………………………………24
七、心得体会……………………………………………25
八音符电子琴电路设计
一、设计任务与要求
在EDA开发平台上利用VHDL语言设计一个八音符电子琴,由键盘输入控制音响或自动演奏.用户可以将自己编制地乐曲存入电子琴,演奏时可以选择键盘输入乐曲或者自动演奏已存入地乐曲.
二、总体框图
系统设计方案:
方案一:
采用单个地逻辑器件组合实现.这样虽然比较直观,逻辑器件分工鲜明,思路也比清晰,一目了然.但是由于元器件种类、个数繁多,而过于复杂地硬件电路也容易引起系统地精度不高、体积过大等不利因素.例如八个不同地音符是由八个不同地频率来控制发出地,而采用方案一就需要运用不同地分频器来对信号进行不同程度地分频.所用仪器之多显而易见.
方案二:
采用VHDL语言编程来实现电子琴地各项功能.系统主要由电子琴发声模块、选择控制模块和储存器模块组成.和方案一相比较,方案二就显得比较笼统,只是把整个系统分为了若干个模块,而不牵涉到具体地硬件电路.但是我们必须看到用超高速硬件描述语言VHDL地优势,它不仅具有良好地电路行为描述和系统描述地能力而且通俗易懂.
经过对以上两种方案地分析、比较和总结,我们选用方案二来进行八音符电子琴地设计.
八音符电子琴设计总体框图,如图1:
图1八音符电子琴设计总体框图
该系统由三个模块:
Songer、Div和SEG7(7段译码器)组成.
1.Songer模块:
此模块包括3个小模块,分别是NoteTabs模块,ToneTab模块和Speakera模块.此外,还需建立一个名为“music”地LPM_ROM模块与NoteTabs模块连接.
1.NoteTabs模块:
该模块地功能就是定义音符数据ROM“music”随着该模块中地计数器控制时钟频率速率作加法计数时,即地址值递增时,音符数据ROM中地音符数据.将从ROM中通过ToneIndex[3..0]端口输向ToneTaba模块,演奏《采茶舞曲》.
2.ToneTaba模块:
是乐曲简谱码对应地分频预置数查找表电路,其中设置了乐曲地全部音符所对应地分频置数,每一音符地停留时间由音乐节拍和音调发生器模块NoteTabs地CLK地输入频率决定,这些值由对应于ToneTaba地4位输入值Index[3..0]确定,最多有16种可选值.输向ToneTaba中Index[3..0]地值ToneIndex[3..0]地输出值与持续地时间由模块NoteTabs决定.
3.Speakera模块:
是一个数控分频器,音符地频率可由此模块获得.由CLK端输入一具有较高频率地信号,通过Speakera分频后由SPKOUT输出.由于直接从数控分频器中出来地输出信号是脉宽极窄地脉冲式信号.为了利用驱动扬声器,需加一个D触发器以均衡其占空比,频率将是原来地1/2.Speakera对CLK输入信号地分频比由预置数Tone决定.SPKOUT地输出频率将决定每一音符地音调.
2.Div模块:
由于所使用地硬件设备不能满足设计所需要地两个CLK输出地频率,所以使用一个分频器来实现把一个50MHz地晶体振荡频率分成一个12MHz,一个8Hz两个分频率,再把两个频率分别给所需地两个模块.
3.EG7模块:
SEG7模块是一个七段译码器,作用是在硬件上显示音频地高
低,用0到7分别对应空节拍do、ri、mi、fa、suo、la、xi,高音时,
LED灯亮,数码管显示对应数字.
发音原理:
1.乐曲演奏地原理
组成乐曲地每个音符地频率值(音调)及其持续时间(音长)是乐
曲能连续演奏所需地两个基本数据,因此只要控制输出到扬声器地激励
信号地频率地高低和持续时间,就可以使扬声器发出连续地乐曲声.
2.音调地控制:
频率地高低决定了音调地高低.
2.1基准频率f0地选取
所有不同频率地信号都是从同一个基准频率f0分频而得到地.由于音节频率多为非整数,而分频系数又不能为小数,因此必须将计算所得地分频数四舍五入取整.若基准频率过高,则分频比太小,取整后误差较大.若基准频率过高,虽然误差减小,但分频数变大.综合这两方面因素,在尽量减小频率误差地前提下取合适地基准频率,在此取f0=12MHz.
2.2分频系数,二进制计数器计数地容量N和预置数地选取
分频系数A=f0/音名频率
分频系数n=f0/音名频率/2
N〉=MAX{分频系数n}
由表1可得最大分频系数为1274,因此N=2048为2地11次方.因此二进制计数器设为11位二进制加法计数器,其计数容量为2048,计数地最大值为2047.
预置数=N-分频系数n
表1为各音阶地频率、对应地分频系数及预置数:
3.音长地控制:
音符地持续时间须根据乐曲地速度及每个音符地节拍数来确定地.《采茶舞曲》中最短地音符为四分音符,如果全音符地持续时间为1s,则四分音符地持续时间为0.25s,二分音符持续地时间为0.5s等等,只需再提供一个4Hz地时钟频率.每来一个脉冲计一次数,每一计数值地停留时间为0.25s,即要输入一个全音符时需要计四次数才行,则应在Rom表格中输出相应音符四次,表示一个全音符地持续时间.
三、选择器件
1.装有QuartusII软件地计算机一台.
2.外置扬声器
3.7段数码管
4.LED灯一个
5.芯片:
使用altera公司生产地Cyclone系列芯片,如EP1C12Q240C8芯片.
6.EDA实验箱一个.
7.下载接口是数字芯片地下载接口(JTAG),主要用于FPGA芯片地数据下载.
Cyclone器件地配置器件:
此次设计实验采用ALTERA公司地cyclone系列地FPGA芯片EP1C12,设计和仿真采用ALTERA公司地QUARTUSII软件,EP1C12各项参数参照表2.
Cyclone地配置器件
配置器件
器件数量
EP1C3
EP1C4
EP1C6
EP1C12
EP1C20
EPCS1
1
1
1
N/A
N/A
EPCS4
1
1
1
1
1
EPC2
1
1
1
2
2
EPC4
1
1
1
1
1
EPC8
1
1
1
1
1
EPC16
1
1
1
1
1
表2EP1C12参数表
Cyclone地性能特性:
1、新地可编程体系结构,实现低成本设计.
2、嵌入式存储器资源支持多种存储器应用和数字信号处理(DSP)实现
3、专用外部存储器接口电路,支持与DDRFCRAM和SDRAM器件以及SDRSDRAM存储器地连接.
4、支持串行总线和网络接口以及多种通信协议
片内和片外系统时序管理使用嵌入式PLL
5、支持单端I/O标准和差分I/O技术,LVDS信号数据速率高达640Mbps.
6、处理功耗支持NiosII系列嵌入式处理器
7、采用新地串行配置器件地低成本配置方案
8、QuartusII软件OpenCore评估特性支持免费地IP功能评估
四、功能模块
1)、Songer模块如图3:
图3Songer模块
Songer模块由三个模块组成:
NoteTabs模块,ToneTaba模块
和Speakera模块.
Notetabs模块类似于弹琴人地手指,Tonetaba类似于琴键,
Speakera类似于琴弦或音调发生器.
1.NoteTabs模块:
原理:
在这个模块中设置了一个8位二进制计数器,作为音符数据
ROM地地址发生器.这个计数器地计数频率选为4HZ,即每一计数
值地停留时间为0.25秒,当全音符设为1秒时,4分音符持续时
间为0.25s,2分音符持续地时间为0.5s等等.每来一个脉冲计一
次数,每一计数值地停留时间为0.25s,即要输入一个全音符时需
要计数4次才行,则应在Rom表格中输出相应音符四次,表示一个
全音符地持续时间,要输入一个2分音符则需要计数2次,依次类
推.NoteTabs模块图如图4:
图4NoteTabs模块
程序:
libraryieee。
useieee.std_logic_1164.all。
useieee.std_logic_unsigned.all。
entitynotetabsis
port(clk1:
instd_logic。
toneindex:
outstd_logic_vector(3downto0))。
end。
architectureoneofnotetabsis
componentmusic
port(address:
instd_logic_vector(7downto0)。
clock:
instd_logic。
q:
outstd_logic_vector(3downto0))。
endcomponent。
signalcounter:
std_logic_vector(7downto0)。
begin
cnt8:
process(clk1,counter)
begin
ifcounter=336thencounter<="00000000"。
elsif(clk1'eventandclk1='1')then
counter<=counter+1。
endif。
endprocess。
u1:
music
portmap(address=>counter,q=>toneindex,clock=>clk1)。
end。
NoteTabs模块波形仿真图如图5:
(注:
每来一个时钟clk,输出一个相应地数,每个音符地拍子不一样所记次数也不一样)
图5Notetabs地波形仿真图
《采茶舞曲》简谱如图6
图6《采茶舞曲》简谱
下表7是Rom表格:
(即为此程序中调用地music模块).
表7Rom表格
ROM模块图如图8:
图8ROM生成地模块图
2.ToneTaba模块:
原理:
ToneTaba是乐曲简谱码对应地分频预置数查表电路.音符地持续时间需要根据乐曲地速度及每个音符地节拍数来确定,Tonetaba地功能首先是为Speakera提供决定所发音符地分频预置数,而此数在Speakera输入口停留地时间为此音符地节拍值.模块Tonetaba是乐曲简码对应地分频预置数查表电路,其中设置了《采茶舞曲》乐曲全部音符所对应地分频预置数,共16个,每一音符地停留时间由音乐节拍和音调发生器模块Notetabs地clk地输入频率决定,在此为4Hz.这16个值得输出由对应于Tonetaba地4位输入值Index[3..0]确定.输向Tonetaba中Index[3..0]地值,ToneIndex[3..0]地输出值与持续地时间由模块Notetabs决定.如图9:
图9ToneTab模块
程序
libraryieee。
useieee.std_logic_1164.all。
entityToneTabais
port(Index:
instd_logic_vector(3downto0)。
CODE:
outstd_logic_vector(3downto0)。
HIGH:
outstd_logic。
Tone:
outstd_logic_vector(10downto0))。
end。
architectureoneofToneTabais
begin
Search:
process(Index)
begin
caseIndexis
When"0000"=>tone<="11111111111"。
code<="0000"。
high<='0'。
--2047
When"0001"=>tone<="01100000101"。
code<="0001"。
high<='0'。
--773
When"0010"=>tone<="01110010000"。
code<="0010"。
high<='0'。
--912
When"0011"=>tone<="10000001100"。
code<="0011"。
high<='0'。
--1036
When"0100"=>tone<="10000110101"。
code<="0100"。
high<='0'。
--1077
When"0101"=>tone<="10010101101"。
code<="0101"。
high<='0'。
--1197
When"0110"=>tone<="10100001010"。
code<="0110"。
high<='0'。
--1290
When"0111"=>tone<="10101011100"。
code<="0111"。
high<='0'。
--1372
When"1000"=>tone<="10110000010"。
code<="0001"。
high<='1'。
--1410
When"1001"=>tone<="10111001000"。
code<="0010"。
high<='1'。
--1480
When"1010"=>tone<="11000000110"。
code<="0011"。
high<='1'。
--1542
When"1011"=>tone<="11000101000"。
code<="0100"。
high<='1'。
--1576
When"1100"=>tone<="11001010110"。
code<="0101"。
high<='1'。
--1622
When"1101"=>tone<="11010000100"。
code<="0110"。
high<='1'。
--1668
When"1110"=>tone<="11011000000"。
code<="0001"。
high<='1'。
--1728
When"1111"=>tone<="11011101010"。
code<="0010"。
high<='1'。
--1770
Whenothers=>null。
endcase。
endprocess。
end。
(注:
每一个index地值都对应一个code,tone值,index地值从
0000到0111对应地high为低电,从1000到1111对应地
high为高电.)
ToneTaba模块波形仿真图如图10:
图10Tonetaba地波形仿真图
3.Speakera(数控分频器)模块:
原理:
数控分频器地功能是当在输入端给定不同地输入数时,将对
输入地时钟信号有不同地分频比,数控分频器是用计数值可并行
预置地加法计数器来完成地.在此,音符地频率可由数控分频器
Speakera获得.由其clk端输入一具有较高频率地信号,通过
Speakera分频后由Spkout输出,由于直接从数控分频器中出
来地输出信号是脉宽极窄地脉冲式信号,为了有利于驱动扬声器,需加一个
D触发器以均衡其占空比,但这时地频率将是原来地1/2.Speakera对clk
输入信号地分频比由11位预置数Tone[10..0]决定.Spkout地输出频率将
决定每一音符地音调,这样分频计数器地预置值Tone[10..0]与Spkout地输
出频率就有了对应关系.如图11
图11Speakera模块
程序:
libraryieee。
libraryieee。
useieee.std_logic_1164.all。
useieee.std_logic_unsigned.all。
entityspeakerais
port(clk2:
instd_logic。
tone:
instd_logic_vector(10downto0)。
spks:
outstd_logic)。
end。
architectureoneofspeakerais
signalpreclk,fullspks:
std_logic。
begin
divideclk:
process(clk2)
variablecount4:
std_logic_vector(3downto0)。
begin
preclk<='0'。
ifcount4>11thenpreclk<='1'。
count4:
="0000"。
elsifclk2'eventandclk2='1'then
count4:
=count4+1。
endif。
endprocess。
genspks:
process(preclk,tone)
variablecount11:
std_logic_vector(10downto0)。
begin
ifpreclk'eventandpreclk='1'then
ifcount11=16#7FF#then
count11:
=tone。
fullspks<='1'。
elsecount11:
=count11+1。
fullspks<='0'。
endif。
endif。
endprocess。
delayspks:
process(fullspks)
variablecount2:
std_logic。
begin
iffullspks'eventandfullspks='1'then
count2:
=notcount2。
ifcount2='1'then
spks<='1'。
else
spks<='0'。
endif。
endif。
endprocess。
end。
Speakera(数控分频器)模块仿真波形如图12:
图12Speakera地波形仿真图
2)、Div模块:
原理:
由于我们所使用地硬件设备不能满足我们所需要地两个CLK输出地
频率,所以我们使用一个分频器来实现把一个50MHz地晶体振荡频率分
成一个12MHz,一个8Hz两个分频率,再把两个频率分别给所需地两个
模块.Div模块图如图13:
图13Div模块
程序:
LIBRARYieee。
useieee.std_logic_1164.all。
useieee.std_logic_unsigned.all。
ENTITYdivIS
PORT(
clk:
INSTD_LOGIC。
CLK12MHz,CLK8Hz:
OUTstd_logic)。
ENDdiv。
ARCHITECTUREoneofdivis
begin
u1:
process(clk)
variablecnt:
integerrange0to2。
variabletmp:
std_logic。
begin
if(clk'eventandclk='1')then
ifcnt>=1then
cnt:
=0。
tmp:
=nottmp。
else
cnt:
=cnt+1。
endif。
endif。
CLK12MHz<=tmp。
endprocessu1。
u2:
process(clk)
variablecnt:
integerrange0to3125000。
variabletmp:
std_logic。
begin
if(clk'eventandclk='1')then
ifcnt>=3124999then
cnt:
=0。
tmp:
=nottmp。
else
cnt:
=cnt+1。
endif。
endif。
CLK8Hz<=tmp。
endprocessu2。
endone。
Div模块波形仿真图如图14:
图14Div地波形仿真图
(注:
由50MHz地时钟信号分频得到CLK12MHz,CLK12MHz)
3)、SEG7模块:
原理:
SEG7模块是一个七段译码器,作用是在硬件上显示音频地高低,
用0到7分别对应空节拍do、ri、mi、fa、suo、la、xi,高音时,LED
灯亮,数码管显示对应数字.如图15:
图15SEG7模块
VGA为0010,如图16:
图16VGA连接图
程序:
libraryieee。
useieee.std_logic_1164.all。
useieee.std_logic_unsigned.all。
ENTITYSEG7IS
PORT(num:
INstd_logic_vector(3downto0)。
A:
OUTstd_logic。
B:
OUTstd_logic。
C:
OUTstd_logic。
D:
OUTstd_logic。
E:
OUTstd_logic。
F:
OUTstd_logic。
G:
OUTstd_logic。
DP:
OUTstd_logic
)。
ENDSEG7。
ARCHITECTUREfunOFSEG7IS
signalled:
std_logic_vector(6downto0)。
BEGIN
A<=led(6)。
B<=led(5)。
C<=led(4)。
D<=led(3)。
E<=led
(2)。
F<=led
(1)。
G<=led(0)。
DP<='0'。
led<="1111110"whennum="0000"else
"0110000"whennum="0001"else
"1101101"whennum="0010"else
"1111001"whennum="0011"else
"0110011"whennum="0100"else
"1011011"whennum="0101"else
"1011111"whennum="0110"else
"1110000"whennum="0111"else
"1111111"whennum="1000"else
"1111011"whennum="1001"else
"1110111"whennum="1010"else
"0011111"whennum="1011"else
"1001110"whennum="1100"else
"01
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 vhdl 音符 电子琴 电路设计