




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、VHDL硬件描述语言程序设计简易电子琴演奏器姓名:chi目录一、设计课题的任务要求3二、系统设计3三、仿真波形及波形分析11四、源程序12五、功能说明41六、元器件清单及资源利用情况41七、故障及问题分析43八、总结和结论44一、 设计课题的任务要求基本要求:1、 用8×8点阵显示“1 2 3 4 5 6 7”七个音符构成的电子琴键盘。其中点阵的第一列用一个LED点亮表示音符“1”,第二列用二个LED点亮表示音符“2”,依此类推,如下图所示。1 2 3 4 5 6 7图1 点阵显示的电子琴键盘2、 用BTN1BTN7七个按键模拟电子琴手动演奏时的“1 2 3 4 5 6 7”七个音符
2、。当某个按键按下时,数码管显示相应的音符,点阵上与之对应的音符显示列全灭,同时蜂鸣器演奏相应的声音;当按键弹开时数码管显示的音符灭掉,点阵显示恢复,蜂鸣器停止声音的输出。下图所示为按下BTN3按键时点阵的显示情况。1 2 3 4 5 6 7图2 按键按下后的点阵显示3、 由拨码开关切换选择高、中、低音,并用数码管进行相应的显示。4、 通过按键BTN0进行复位,控制点阵显示图1的初始状态。提高要求:1、 可通过一个拨码开关进行手动/自动演奏的切换,并与点阵显示配合增加自动演奏乐曲的功能。2、 增加手动演奏的音符存储、播放功能。二、 系统设计1. 设计思路简易电子琴的制作主要是利用不同频率的波来驱
3、动蜂鸣器发出声响。通过输入不同的音符来设置不同的分频系数,使得50MHz的主频分频出不同频率的波。同时,演奏的音符还可以通过数码管和8*8点阵来动态显示。根据系统设计要求,该电子琴设计采用自顶向下的设计方法。整体的功能通过不同的底层模块配合来完成电子琴的功能。底层模块主要包括乐曲自动演奏模块、分频预置值产生模块和数控分频模块,数码管显示模块,8*8点阵显示模块五部分组成。用这种设计思路把整个系统分为了若干个模块,然后再在顶层文件中将各个模块组合在一起,从而体现出超、高速硬件描述语言VHDL的优势, 关于提高要求中通过一个拨码开关进行手动/自动演奏的切换,并与点阵显示配合增加自动演奏乐曲的功能,
4、我打算将一首曲子的音符储存在自动播放的数组里面,然后通过计数器来顺序播放储存的音符。关于提高要求中的手动演奏的音符存储、播放功能,我打算通过编程实现类似数据结构中队列的模块,来储存手动输入的音符,然后在要播放的时候,队列里面的音符依次出队,从而实现音符储存播放的功能。2. 总体框图数码管显示8*8点阵显示蜂鸣器输出音符输入高低音,自动手动图3简易电子琴总体结构框图是否自动播放查找对应的频率值结束开始输入按键点阵显示蜂鸣器输出数码管显示选择高低音是否图4简易电子琴逻辑流程图图5简易电子琴VHDL电路原理图3. 分块设计(1) 分频模块div0由于实验电路板的主频是50Mhz,为了数码管和点阵的刷
5、新显示,我们必须将50Mhz的频率进行分频。分频的程序来自电路中心的网站上面。在这个模块里,我设置分频系数为cnt=2499。从实验结果看,这个分频对数码管和点阵的显示有很好的效果(2) 数码管显示模块shuma我使用了2个数码管,第一个数码管显示17的音符,第二个数码管显示相关的信息,比如高音用H表示,低音用L表示,自动播放用A表示。两个数码管分别刷新,但由于刷新频率太快,人眼不能察觉,以为是两个数码管是同时亮的。在程序中我们通过duan : out std_logic_vector(7 downto 0)和 cat : out std_logic_vector(5 downto 0)来控制
6、数码管的显示。当输入不同的音符和不同的控制信息时,duan和cat向量都有不同的值与之对应。(3) 8*8点阵显示模块dianzhen8*8点阵的显示和数码管的显示运用了同样的原理,在程序中我们通过row : out std_logic_vector(7 downto 0)和col : out std_logic_vector(7 downto 0)这两个向量来控制点阵的显示。当输入不同的音符时,点阵显示相应的形状。(4) 音符产生模块auto。这个模块的功能是,选择的不同模式来产生不同的音符。当选择自动播放模式时,随着计数器count的值增加,即地址值递增时,程序自动读取出事先储存的音符,并
7、把这个音符输出。当选择手动演奏模式时,直接将通过BTN1BTN7输入的向量当做音符输出yin :out std_logic_vector(6 downto 0);。(5) 分频预置值产生模块该模块的功能是通过音符以及高低音选项来查表找到对应的频率值。在程序中设置了全部音符对应的分频预置数。通过判断音符产生模块输出的音符 yin :in std_logic_vector(6 downto 0),以及拨码开关的高低音highlow :in std_logic_vector(1 downto 0)控制键,来查找出该音符的频率值,然后将该频率赋值给tone :out integer range 0 t
8、o 2000000);。 (6) 数控分频发声模块从实验板上面输入的时钟是50MHz的,必须经过分频后由clk_out输出,驱动蜂鸣器发声。Clk_out的输出频率就对应着音符的音调。分频系数由来自分频预置值模块的tone :out integer range 0 to 2000000)。由于直接从数控分频器中出来的输出信号是脉宽极窄的脉冲式信号。为了利用驱动蜂鸣器,需要再增加一个进程,多波形进行整理,均衡占空比三、 仿真波形及波形分析1. 数码管显示模块仿真波形 波形分析:不同的yin,和highlow组合,数码管显示不同的字符。duan0duan7对应着数码管的a段到h段,cat0cat5
9、控制不同的数码管2. 点阵显示模块仿真波形波形分析:不同的yin输入,点阵的col和row会有不同的波形,利用clk_in的上升沿来动态扫描点阵。从而得显示出指定的图形。3. 自动播放模块仿真波形波形分析:当auto 置1,clear置0,yin_out输出储存在程序里面的曲子音符,这时候相当于自动播放。当auto置0,clear置0,yin_out输出从BTN1BTN7读取的手动输入的信号,这时候相当于手动演奏。4. 分频预置值产生模块仿真波形波形分析:输入不同的高低音highlow,和音符yin,输出不同的tone。而tone将作为发声模块的分频预置值四、 源程序1. 分频模块源程序lib
10、rary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity div0 isport(clk_in : in std_logic; -输入时钟 clk_tmp : out std_logic); -输出时钟end;architecture b of div0 is signal clk : std_logic;beginp0:process(clk_in) variable cnt : integer range 0 to 2499;beginif (clk_in'event and clk_i
11、n='1') thenif cnt=2499 then -分频系数为2499cnt:=0;clk<= not clk;elsecnt:=cnt+1; -每个输入时钟上升沿到来时cnt加1end if;end if;end process p0;clk_tmp<=clk;end b ;2. 数码管显示源程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity shuma isport(clk_in : in std_logic; -以分频的时钟输入 yin : i
12、n std_logic_vector(6 downto 0); -输入音符 highlow :in std_logic_vector(1 downto 0); -输入高低音 auto : in std_logic; -自动播放 auto1 : in std_logic; -自动播放1 duan : out std_logic_vector(7 downto 0); cat : out std_logic_vector(5 downto 0) );end;architecture b of shuma issignal duant : std_logic_vector(7 downto 0);s
13、ignal catt : std_logic_vector(5 downto 0);beginp1: process(clk_in,yin,highlow,auto,auto1) beginif auto ='1' thencatt<="111101"duant<="00111111" -显示“8”表示自动播放elsif auto1 ='1' then catt<="111101"duant<="01111111"-显示“0”表示试音elsif auto =&
14、#39;0' then if(clk_in ='0') thencase yin iswhen "0000001" => catt<="111110"duant<="00000110" -显示“1”when "0000010" => catt<="111110"duant<="01011011"-显示“2”when "0000100" => catt<="111110&quo
15、t;duant<="01001111"-显示“3”when "0001000" => catt<="111110"duant<="01100110"-显示“4”when "0010000" => catt<="111110"duant<="01101101"-显示“5”when "0100000" => catt<="111110"duant<="
16、01111101"-显示“6”when "1000000" => catt<="111110"duant<="00000111"-显示“7”when others=> catt<="111111"duant<="00000000"end case; elsif (clk_in ='1') thencase highlow iswhen "10" => catt<="111101"du
17、ant<="01110100" -显示“L”when "01" => catt<="111101"duant<="00111000" -显示“H”when others=> catt<="111111"duant<="00000000" end case; end if;end if; end process p1; cat<= catt; duan<= duant;end b;3. 点阵显示源程序library ieee
18、;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity dianzhen isport(clk_in : in std_logic; -时钟输入 yin : in std_logic_vector(6 downto 0); -输入音符 row : out std_logic_vector(7 downto 0); -点阵行向量 col : out std_logic_vector(7 downto 0) -点阵列向量 );end;architecture b of dianzhen issignal count :
19、 integer range 0 to 6;signal rowt : std_logic_vector(7 downto 0);signal colt : std_logic_vector(7 downto 0);beginp1:process(clk_in)beginif (clk_in'event and clk_in='1') thenif count = 6 then count<=0;elsecount<=count+1;-用count来记数end if;end if;end process p1;p2: process(count,yin) b
20、egin if (yin = "0000001") thencase count is-点阵显示,表示“1”音符 when 0=> rowt<="11111110"colt<="01111110" when 1=> rowt<="11111101"colt<="01111110" when 2=> rowt<="11111011"colt<="01111100" when 3=> rowt<
21、="11110111"colt<="01111000" when 4=> rowt<="11101111"colt<="01110000" when 5=> rowt<="11011111"colt<="01100000" when 6=> rowt<="10111111"colt<="01000000" when others=> rowt<="1111
22、1111"colt<="00000000"end case; elsif (yin = "0000010") thencase count is-点阵显示,表示“2”音符 when 0=> rowt<="11111110"colt<="01111101" when 1=> rowt<="11111101"colt<="01111100" when 2=> rowt<="11111011"col
23、t<="01111100" when 3=> rowt<="11110111"colt<="01111000" when 4=> rowt<="11101111"colt<="01110000" when 5=> rowt<="11011111"colt<="01100000" when 6=> rowt<="10111111"colt<="0100
24、0000" when others=> rowt<="11111111"colt<="00000000"end case;elsif (yin = "0000100") thencase count is-点阵显示,表示“3”音符 when 0=> rowt<="11111110"colt<="01111011" when 1=> rowt<="11111101"colt<="01111010"
25、; when 2=> rowt<="11111011"colt<="01111000" when 3=> rowt<="11110111"colt<="01111000" when 4=> rowt<="11101111"colt<="01110000" when 5=> rowt<="11011111"colt<="01100000" when 6=> ro
26、wt<="10111111"colt<="01000000" when others=> rowt<="11111111"colt<="00000000"end case;elsif (yin = "0001000") thencase count is-点阵显示,表示“4”音符 when 0=> rowt<="11111110"colt<="01110111" when 1=> rowt<=&q
27、uot;11111101"colt<="01110110" when 2=> rowt<="11111011"colt<="01110100" when 3=> rowt<="11110111"colt<="01110000" when 4=> rowt<="11101111"colt<="01110000" when 5=> rowt<="11011111&quo
28、t;colt<="01100000" when 6=> rowt<="10111111"colt<="01000000" when others=> rowt<="11111111"colt<="00000000"end case;elsif (yin = "0010000") thencase count is -点阵显示,表示“5”音符 when 0=> rowt<="11111110"colt&l
29、t;="01101111" when 1=> rowt<="11111101"colt<="01101110" when 2=> rowt<="11111011"colt<="01101100" when 3=> rowt<="11110111"colt<="01101000" when 4=> rowt<="11101111"colt<="0110000
30、0" when 5=> rowt<="11011111"colt<="01100000" when 6=> rowt<="10111111"colt<="01000000" when others=> rowt<="11111111"colt<="00000000"end case;elsif (yin = "0100000") thencase count is-点阵显示,表示“6”音符 w
31、hen 0=> rowt<="11111110"colt<="01011111" when 1=> rowt<="11111101"colt<="01011110" when 2=> rowt<="11111011"colt<="01011100" when 3=> rowt<="11110111"colt<="01011000" when 4=> rowt&
32、lt;="11101111"colt<="01010000" when 5=> rowt<="11011111"colt<="01000000" when 6=> rowt<="10111111"colt<="01000000" when others=> rowt<="11111111"colt<="00000000"end case;elsif (yin = "1
33、000000") thencase count is-点阵显示,表示“7”音符 when 0=> rowt<="11111110"colt<="00111111" when 1=> rowt<="11111101"colt<="00111110" when 2=> rowt<="11111011"colt<="00111100" when 3=> rowt<="11110111"c
34、olt<="00111000" when 4=> rowt<="11101111"colt<="00110000" when 5=> rowt<="11011111"colt<="00100000" when 6=> rowt<="10111111"colt<="00000000" when others=> rowt<="11111111"colt<=&qu
35、ot;00000000"end case;else case count is-点阵显示,表示不输入音符 when 0=> rowt<="11111110"colt<="01111111" when 1=> rowt<="11111101"colt<="01111110" when 2=> rowt<="11111011"colt<="01111100" when 3=> rowt<="11
36、110111"colt<="01111000" when 4=> rowt<="11101111"colt<="01110000" when 5=> rowt<="11011111"colt<="01100000" when 6=> rowt<="10111111"colt<="01000000" when others=> rowt<="11111111"
37、;colt<="00000000"end case;end if; end process p2; row<= rowt; col<= colt;end b;4. 选择音符及自动播放源程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity auto isport( clk_in :in std_logic;-输入时钟 auto :in std_logic;-自动播放 auto1 :in std_logic;-试音播放 clear :in std_lo
38、gic;-复位 yin_in :in std_logic_vector(6 downto 0);-输入音符 yin_out :out std_logic_vector(6 downto 0); -输出音符end auto;architecture a of auto issignal count : integer range 0 to 35;signal n: integer range 0 to 6;signal yin : std_logic_vector(6 downto 0);begin p1:process(clk_in,clear)variable i : integer ran
39、ge 0 to 63000000;begin if clear ='1' then count<=0; elsif (clk_in'event and clk_in='1') thenif (i=20000000) then i:=0; if count =15 then count <=0;-自动播放count记数 else count <=count+1; end if; if n =6 then n <=0; -试音播放n记数 else n <=n+1; end if;else i:=i+1;end if; end i
40、f;end process p1;p2:process(count,auto,yin_in,clear)begin if clear='1' then yin<="0000000"-音符清零elseif auto ='1' then-自动播放歌曲case count iswhen 1 => yin<="0000100"-3when 2 => yin<="1000000"-7when 3 => yin<="0000100"-3when 4 =&
41、gt; yin<="0100000"-6when 5 => yin<="0010000"-5when 6=> yin<="0100000"-6when 7 => yin<="0000001"-1when 8 => yin<="0000100"-3when 9 => yin<="0010000"-5when 10 => yin<="0000100"-3when 11 => y
42、in<="0000100"-3when 12 => yin<="0001000"-4when 13 => yin<="0000100"-2when 14 => yin<="0001000"-4when others => yin<="0000000"end case;elsif auto1 ='1' thencase n is-试音播放when 0 => yin<="0000001"-1when
43、 1 => yin<="0000010"-2when 2 => yin<="0000100"-3when 3 => yin<="0001000"-4when 4 => yin<="0010000"-5when 5 => yin<="0100000"-6when 6 => yin<="1000000"-7when others => yin<="0000000"end cas
44、e;elseyin<=yin_in;-动手演奏end if;end if;end process p2;yin_out<=yin;end a;5. 预置分频系数模块源代码library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity seletone isport( highlow :in std_logic_vector(1 downto 0); -高低音 yin :in std_logic_vector(6 downto 0);-要演奏的音符 tone :out integer ra
45、nge 0 to 2000000); -预置分频系数end seletone;architecture a of seletone issignal tone0 :integer range 0 to 2000000;begin process(highlow,yin)begin if highlow ="00" thencase yin is-中音部分when "0000001"=> tone0<=523;when "0000010"=> tone0<=587;when "0000100"
46、=> tone0<=659;when "0001000"=> tone0<=698;when "0010000"=> tone0<=784;when "0100000"=> tone0<=880;when "1000000"=> tone0<=988;when others => tone0<=2000000;end case;elsif highlow ="10" then-高音部分case yin iswhen &quo
47、t;0000001"=> tone0<=1045;when "0000010"=> tone0<=1174;when "0000100"=> tone0<=1318;when "0001000"=> tone0<=1396;when "0010000"=> tone0<=1568;when "0100000"=> tone0<=1760;when "1000000"=> tone0<
48、=1975;when others => tone0<=2000000;end case;elsif highlow ="01" then-低音部分case yin iswhen "0000001"=> tone0<=261;when "0000010"=> tone0<=293;when "0000100"=> tone0<=329;when "0001000"=> tone0<=349;when "0010000"
49、;=> tone0<=392;when "0100000"=> tone0<=440;when "1000000"=> tone0<=494;when others => tone0<=2000000;end case; end if;end process ;tone <=tone0;end a;6. 分频发音模块源代码library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity div isport(
50、clk_in : in std_logic;-输入时钟 tone: in integer range 0 to 2000000;-预置频率 clk_out : out std_logic);-输出时钟end div;architecture a of div issignal clk_tmp0 : std_logic;signal clk_tmp1: std_logic;begin p0:process(clk_in, tone)variable cnt : integer range 0 to 49999999;beginif (clk_in'event and clk_in=
51、9;1') then if cnt <12999999/tone then-分频系数 cnt:=cnt+1; clk_tmp0<='1' else cnt:=0; clk_tmp0<='0' end if;end if;end process p0;p1:process(clk_tmp0)variable count :std_logic;beginif(clk_tmp0'event and clk_tmp0='1') thencount:=not count;if count ='1' then
52、clk_tmp1 <='1'-输出平稳的波形elseclk_tmp1 <='0'end if;end if;end process p1;clk_out<=clk_tmp1;end a;7. 电子琴顶层设计library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity dianzq isport(clk : in std_logic;-时钟输入 yin : in std_logic_vector(6 downto 0);-音符输入 highlow:
53、in std_logic_vector(1 downto 0);-高低音输入 auto_in: in std_logic;-自动播放 auto1 : in std_logic;-试音播放 clear : in std_logic;-复位 clk_out: out std_logic;-输出时钟 row : out std_logic_vector(7 downto 0);-点阵显示 col : out std_logic_vector(7 downto 0);-点阵显示 duan : out std_logic_vector(7 downto 0);-数码管显示 cat : out std_l
54、ogic_vector(5 downto 0);-数码管显示end dianzq;architecture a of dianzq iscomponent div0 is-分频模块port(clk_in : in std_logic; clk_tmp : out std_logic);end component;component dianzhen is-点阵显示模块port(clk_in : in std_logic; yin : in std_logic_vector(6 downto 0); row : out std_logic_vector(7 downto 0); col : ou
55、t std_logic_vector(7 downto 0) );end component;component shuma is-数码管显示模块port(clk_in : in std_logic; yin : in std_logic_vector(6 downto 0); highlow :in std_logic_vector(1 downto 0); auto : in std_logic; auto1 : in std_logic; duan : out std_logic_vector(7 downto 0); cat : out std_logic_vector(5 downt
56、o 0) );end component;component auto is-自动播放模块port( clk_in :in std_logic; auto :in std_logic; auto1 : in std_logic; yin_in :in std_logic_vector(6 downto 0); clear : in std_logic; yin_out:out std_logic_vector(6 downto 0); end component;component seletone is-预置分频系数模块port( highlow:in std_logic_vector(1
57、downto 0); yin :in std_logic_vector(6 downto 0); tone :out integer range 0 to 2000000); end component;component div is-分频发音模块port(clk_in : in std_logic; tone : in integer range 0 to 2000000; clk_out : out std_logic);end component;signal yin_tmp :std_logic_vector(6 downto 0);signal tone_tmp : integer
58、 range 0 to 2000000;signal clk_tmp : std_logic;beginu1: auto port map (clk_in=>clk,auto=>auto_in,yin_in=>yin,yin_out=>yin_tmp,clear=>clear,auto1=>auto1);u2: seletone port map (highlow=>highlow,yin=>yin_tmp,tone=>tone_tmp); u3: shuma port map (duan=>duan,cat=>cat,yin=>yin_tmp,clk_in=>c
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年心理咨询师资格考试理论试卷及答案
- 2025年信息与通信工程考试试题及答案解析
- 2025年数字媒体艺术与设计考核试卷及答案
- Riluzole-13C6-PK-26124-sup-13-sup-C-sub-6-sub-生命科学试剂-MCE
- Paulomenol-A-生命科学试剂-MCE
- 2025年设备维护与管理考试试题及答案
- 2025年量子计算原理与应用测试题及答案
- 2025年公共事务与危机管理考试试卷及答案
- 英语语法入门:词性及用法解析
- 酒店经营租赁合同
- 2025年重庆市中考数学试卷真题(含标准答案)
- 农机耕地合同协议书范本
- 精装分包劳务合同协议书
- T/CNESA 1203-2021压缩空气储能系统性能测试规范
- T/CGMA 031003-2020一般用离心空气压缩机
- 2025年四年级下册美术期末测试题附答案
- 店面借给别人合同协议书
- 2024年深圳市中考历史试卷真题(含答案解析)
- 公司内部文件管理规定及办法
- 电子商务概论试题库及答案(共21页)
- 保肝药物及临床应ppt课件
评论
0/150
提交评论