简易电子琴的VHDL仿真跟实现.docx
《简易电子琴的VHDL仿真跟实现.docx》由会员分享,可在线阅读,更多相关《简易电子琴的VHDL仿真跟实现.docx(41页珍藏版)》请在冰豆网上搜索。
![简易电子琴的VHDL仿真跟实现.docx](https://file1.bdocx.com/fileroot1/2022-11/20/c6f4d3e6-0c95-4b0d-95ca-a12ef223bb5e/c6f4d3e6-0c95-4b0d-95ca-a12ef223bb5e1.gif)
简易电子琴的VHDL仿真跟实现
简易电子琴的VHDL
设计与实现
一.设计课题与任务要求:
设计制作一个简易电子琴演奏器。
原理概述:
根据声乐知识,产生音乐的两个因素是音乐频率的持续时间,音乐的十二平均率规定,每两个八音度之间的频率相差一倍,在两个八音度之间,又可分为12个半音。
每两个半音的频率比为4。
另外,音名A(乐谱中的低音6)的频率为440HZ,音名B到C之间,E到F之间为半音,其余为全音。
由此可以计算出乐谱中从低音1到高音1之间每个音名的频率如下表所示。
表1简谱中的音名与频率的关系
音名
频率(Hz)
音名
频率(Hz)
音名
频率(Hz)
低音1
261.63
中音1
523.25
高音1
1046.50
低音2
293.67
中音2
587.33
高音2
1174.66
低音3
329.63
中音3
659.25
高音3
1318.51
低音4
349.23
中音4
698.46
高音4
1396.92
低音5
391.99
中音5
783.99
高音5
1567.98
低音6
440
中音6
880
高音6
1760
低音7
493.88
中音7
987.76
高音7
1975.52
基本要求:
1、用8×8点阵显示“1234567”七个音符构成的电子琴键盘。
其中点阵的第一列用一个LED点亮表示音符“1”,第二列用二个LED点亮表示音符“2”,依此类推,如下图所示。
图1点阵显示的电子琴键盘
2、用BTN1~BTN7七个按键模拟电子琴手动演奏时的“1234567”七个音符。
当某个按键按下时,数码管显示相应的音符,点阵上与之对应的音符显示列全灭,同时蜂鸣器演奏相应的声音;当按键弹开时数码管显示的音符灭掉,点阵显示恢复,蜂鸣器停止声音的输出。
下图所示为按下BTN3按键时点阵的显示情况。
图2按键按下后的点阵显示
3、由拨码开关切换选择高、中、低音,并用数码管进行相应的显示。
4、通过按键BTN0进行复位,控制点阵显示图1的初始状态。
提高要求:
1、可通过一个拨码开关进行手动/自动演奏的切换,并与点阵显示配合增加自动演奏乐曲的功能。
2、增加手动演奏的音符存储、播放功能。
二.系统设计(包括设计思路、总体框图、分块设计)
1.设计思路说明:
电子琴的设计包括七个模块:
弹奏模块keyplay、自动演奏模块autoplay、查表及显示模块table、分频模块fenpin、存储模块store、七段数码管显示模块seg7和点阵的显示模块lattice。
弹奏模块keyplay根据按键动作key,和高中低模式选择mode产生指示音调的index_key。
自动演奏模块autoplay接收50MHz的时钟信号,输出index_auto。
存储录音模块store根据store1选择录音,用数组存储index_key,并将其传输给index_store,作为录音存储的数据。
查表及显示模块table根据按键button,replay选择采用index_key或index_auto或者index_store来查分频系数表,输出分频系数tone。
对于tone的编码,采用了五位编码方式,高2位存储高中低音对应的11、01、00编码,低3位存储相应输入音调对应的二进制编码。
分频模块fenpin接收table输出的分频系数tone,并据此分频,将对应频率的信号buzz输出给扬声器供其发声。
七段数码管显示模块seg7根据对应的按键button,replay选择采用index_key或index_auto或者index_store,分别对应不同的数码管显示输出。
点阵的显示模块lattice根据对应的按键button,replay选择采用index_key或index_auto或者index_store,分别对应不同的数码管显示输出。
这样可以保证在不同的模式下点阵以及数码管都可以对应显示输出。
2.总体框图与流程图
图1系统实现流程图
图2系统设计框图
3.分块设计
系统总体设计:
图3顶层设计
Keyplay模块设计:
将输入key[6..0],mode编码为index_key[4..0]。
index_key[4..0]的高两位表示高、中、低音,00表示低音,01表示中音、11表示高音。
index_key[4..0]低三位表示音调,001表示do,010表示re,以此类推,000表示不发音。
这样可以实现对不同按键模式下的编码,而这些编码会为后续模块例如seg7,lattice所使用。
图4keyplay模块设计
autoplay模块设计:
把50MHz的输入时钟分频为16Hz,作为节拍。
将要自动演奏的歌曲预先写为index_auto的格式(index_auto格式与index_key格式相同)。
以16Hz的频率将index_auto输出。
这里需要用到计数器,此计数器的长度由演奏的歌曲长度而定。
图5autoplay模块设计
查表及显示模块table设计:
(1)输入按键button,replay用于选择模式。
由于是琴键式,不能根据button本身的值来选择模式。
button为1且replay为0则把index_auto赋给内部信号index,button为0且replay为0则把index_key赋给它,button为0且replay为1则把index_store赋给它。
(2)用index来查表,获得分频系数tone,输出。
(3)同时根据index获得编码表示的高、中、低音的音调,输出给数码管和点阵。
图6table模块设计
分频模块fenpin设计:
输入分频系数tone。
(1)设置内部信号i用于计数,clk_data作为分频结果。
每次clk上升沿检测i是否等于tone,相等则把i清零,并使clk_data翻转,否则i自增1。
(2)把clk_data赋给输出信号buzz,由buzz驱动扬声器发声。
图7fenpin模块设计
seg7数码管模块设计:
(1)由button和replay进行调用选择,选择采用index_key或index_auto或者index_store作为对应的信号index输入。
(1)index分别对应不同的数码管显示输出。
图8seg7模块设计
lattice数码管模块设计:
(1)由button和replay进行调用选择,选择采用index_key或index_auto或者index_store作为对应的信号index输入。
(1)index分别对应不同的点阵输出显示
图9lattice模块设计
Store存储模块设计:
Store模块使用了store1和replay控制录音和录音播放的选择。
这里使用了一个二维数组来存储输入的按键信息,然后录音播放时可以按照输入的频率进行对应的播放。
图10store模块设计
三、仿真波形及仿真分析
lattice模块仿真:
波形分析:
这里我只选择性地选取了键盘输入的对应点阵显示,首先键盘输入时button信号为低电平,所以可以从仿真图中看到button信号为低电平,且此时的复位信号无效,为低电平,此时key输入信号有效。
在对应的时钟时钟信号输入下,当键盘输入信号key对应相应的输入时,点阵的行列也会有对应的输出。
由于行的输出是扫描信号,所以对应时钟输入,点阵的行信号在对应的时钟分频下,分别对应一行输出低电平有效,表示扫描至该行,下一个时钟分频对应下一行的低电平输出。
而对应列扫描,根据key输入的情况,分别对应列扫描的电平输出。
如图,例如输入do时,有lie11011111,row01100000。
fenpin模块仿真:
可以看到,2(tone+1)代表的是分频系数,所以对应仿真如上图有,当tone为0时,为2分频,所以buzz对应着时钟的二分频,即分频系数与tone的关系为分频系数=2(tone+1)。
所以在计算每个音调对应的频率时,使用f=2(tone+1)。
Keyplay模块仿真:
如图,对应着不同的key输入和mode选择,会译码为不同的index_key。
比如mode=00,key=0000001时,有index_key译码为00001,mode=00,key=0001000时,有对应index_key译码为00100。
仿真结果与预期要求相符。
autoplay模块仿真:
如图,对应时钟输入产生一定的节拍,在对应的节拍播放我预先设定的乐曲音调,可以看出,对应前三个节拍的为音调mi,接下来有一拍的停顿,接下来又是三个节拍的mi,和预先编写的junglebells的乐曲对应auto-play输出一致。
store模块仿真:
如图,对应时钟上升沿若有按键,则记录;replay有效后,可以看到index_store有对应的赋值,表示有效的按键信息已经被存储。
可以看到根据手动录入的index-key情况,对应replay时的index_store输出分别为10001,10110,01011……
Seg7模块仿真:
如图所示,对应的cat输出为时钟扫描信号,所着时钟变化,cat0,cat1,cat2,cat3,cat4,cat5依次出现低电平,表示对应的选通管有效,而A,B,C,D,E,F,G,DP则根据输入的key而变,可以看到,对应mi的输入的时候,数码管A,B,C,D,E,F,G,DP分别对应1,1,1,1,0,0,1,0,恰好可以显示数码管上的3字样。
四、源程序(要有注释)
electrorgan.vhl--顶层文件
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entityelectrorganis--作为顶层文件,它包含实现功能用到的所有端口
port(clk:
instd_logic;
key:
instd_logic_vector(6downto0);
mode:
instd_logic_vector(1downto0);
cat:
outstd_logic_vector(5downto0);
clr:
instd_logic;
button:
instd_logic;
replay:
instd_logic;
spkout:
outstd_logic;
store1:
instd_logic;
Atop:
OUTstd_logic;
Btop:
OUTstd_logic;
Ctop:
OUTstd_logic;
Dtop:
OUTstd_logic;
Etop:
OUTstd_logic;
Ftop:
OUTstd_logic;
Gtop:
OUTstd_logic;
DPtop:
OUTstd_logic;
lietop:
outstd_logic_vector(7downto0);--列
comtop:
outstd_logic_vector(7downto0));--行
endelectrorgan;
architecturebehaveofelectrorganis
componentautoplay--这里声明了顶层文件中包含的各模块
port(clk:
instd_logic;
clr:
in