1、蜂鸣器音乐发生器实验报告蜂鸣器音乐发生器实验报告1、实验目的 (1)学习用数控分频器设计蜂鸣器音乐发生电路。 (2)了解乐谱的基本知识,可以将乐谱转换为Quartus II 文件,掌握其演奏的原理。 (3)掌握设计中各模块的功能,能够填入并演奏新的曲子。2、实验设备与器件 Quartus II 软件、EP2C8Q208C8实验箱3、实验方案设计 1. 实验可实现的功能 (1)蜂鸣器可以演奏四首音乐,四首音乐通过两个拨码开关控制,可以随意更改想听的曲目。 (2)在播放音乐的同时,用一位数码管显示当前音乐的简谱,并且用两个发光二极管显示高、中、低不同的音调。 (3)在用拨码开关选择曲目的同时,可以
2、在LCD1602液晶屏上看到当前音乐的名称。 2. 音频方案设计 蜂鸣器音乐发生器的基本原理:组成乐曲的每个音调的频率值以及音长所延续的时间是乐曲能够连续演奏的两个基本数据,所以只要控制输出到蜂鸣器的时钟信号频率的高低和持续的时间,就可以使蜂鸣器发出连续的乐曲声。 (1)音调频率值的控制 简谱中音调与音频的对应关系如表3.2.1所示,表中的低、中、高音的频率遵循二倍规则,就是说中音1是低音1频率的2倍,高音1是中音1频率的2倍,以此类推。已知低音的频率,可以通过如下的MATLAB程序计算出中、高音的频率,并且可以得出各音调的分频值与频率预直数,其中预置数是用11位计数器来表示的。计算中、高音及
3、各音调分频值与频率预置数的MATLAB程序:clc;f=50000000; %50MHzbilv=2(1/12); %相邻音调频率之间的比率a(6)=440.0; %低音6的频率为440Hza(7)=a(6)*bilv*bilv; %低音7的频率a(5)=a(6)/bilv/bilv; %低音5的频率a(4)=a(5)/bilv/bilv; %低音4的频率a(3)=a(4)/bilv; %低音3的频率a(2)=a(3)/bilv/bilv; %低音2的频率a(1)=a(2)/bilv/bilv; %低音1的频率b=a*2; %中音的频率c=b*2; %高音的频率counter=211; %分频
4、值对应的位数为11位f=f/50/2; %50MHz,50分频,再2分频for i=1:7 zhia(i)=counter-f/a(i); %低音的分频预置数 zhib(i)=counter-f/b(i); %中音的分频预置数 zhic(i)=counter-f/c(i); %高音的分频预置数end音调、分频值及频率预置数的表格如下:表3.2.1 音符、音频及其预置数低音音符1234567音频/Hz262294330349392440494预置数1373455316167729121036中音音符1234567音频/Hz523587659698784880988预置数1092119712901
5、332141014801542高音音符1234567音频/Hz1047117513191397156817601976预置数1570162216691690172917641795 (2)音调持续时间的控制音乐中的银除了有高低音之分外,还有长短之分。简谱中用一条横线“”在音符的右面或者下面来标注音的长短。表3.2.2列出了常用音符及其长度标记。表3.2.2 常用音符及其长度标记音符名称写法时值全音符1四拍二分音符1二拍四分音符1一拍八分音符1半拍十六分音符1四分之一拍从表3.2.2可以看出横线有记在音符后面的,也有记在音符下面的,横线标记的位置不同,被标记音符的时值也不同。要使音符时值延长,在
6、四分音符右边加横线“”,这时的横线叫做延时线。延时线越多,音调持续的时间就越长。音乐中除了有音的高低、长短之外,也有音的休止。表示音的休止的符号叫休止符,用“0”标记。每增加一个0,就增加一个四分休止符的时值。3.系统工作原理本系统共分为4个模块组成,其中Songer.v是顶层设计文件,其内部有4个功能模块:jianpu.v、zhuanhuan.v、fenpin.v、lcd1602.v,功能模块如图3.3.1所示。图3.3.1 系统功能模块电路 (1)音符的频率可以由图3.3.1中的模块fenpin获得。这是一个数控分频器,由其clk端输入50MHz的时钟信号,通过fenpin分频之后由spk
7、out输出。fenpin对clk输入信号的分频比由11位预置数tone决定。Spkout的输出频率将决定每一音符的音调。这样,分频预置数tone与spkout的输出频率就对应起来了。(2)音符的持续时间是根据乐曲的速度及每个音符的节拍数来确定的,图3.3.1中模块zhuanhuan的功能首先是为fenpin提供决定所发音符分频预置数,而此数在fenpin输入口停留的时间即为此音符的节拍值。模块zhuanhuan是乐曲简谱与相应的分频预置数之间的转换电路,其中设置了高、中、低音全部音符所对应的分频预置数,共21个,每一音符的停留时间由音乐节拍和音调发生器模块jianpu的clk的输入频率决定,这
8、里为4Hz。这21个值的输入由对应于zhuanhuan的5位输入值index确定,而index最多有32种可选值。Toneindex输向zhuanhuan中的index,其值与持续时间由模块jianpu决定。(3)在jianpu中设置了,一个9位二进制计数器,作为简谱数据ROM的地址指针。这个计数器的计数频率选为4Hz,即每一计数值的停留时间为0.25s,恰为当全音符设为1s时,四四拍的4分音符的持续时间。ROM中的低音用07表示,中音在低音的基础上再加7,用814表示,同理高音用1521表示。当jianpu中的计数器按4Hz的时钟速率做加法计数时,ROM中的简谱通过toneindex端口输向
9、zhuanhuan模块,乐曲就可以连续的演奏了。此外还设置了一个两位的乐曲选择端sel,当sel为00时,可演奏高、中、低音的循环演奏;当sel为01时,演奏两只老虎;当sel为10时,演奏天空之城;当sel为11时,演奏快点告诉你。 (4)在lcd1602模块中设置了歌曲名称显示功能,由sel作为选择端口,当sel为00时,可以在lcd1602液晶显示屏的第一行显示“gao zhong di yin”;当sel为01时,显示“liang zhi lao hu”;当sel为10时,显示“tiankongzhicheng”;当sel为11时,显示“kuaidiangaosuni ”。4.各模块程
10、序设计(1)蜂鸣器音乐发生器顶层程序设计module Songer(song_sel,clk,ledpos,ledneg,spkout,sms,smb,rst_n,lcd_data,lcd_e,lcd_rs,lcd_rw,SEL0,SEL1,SEL2);input 1:0 song_sel; /对四首乐曲进行选择input clk; /音调频率信号input rst_n; /节拍频率信号output 1:0 ledpos; /发光二极管的阳极output 3:0 ledneg; /发光二极管的阴极output 7:0 sms; /数码管的段选output 7:0 smb; /数码管的位选out
11、put spkout; /蜂鸣器输出output 7:0 lcd_data; /数据总线output lcd_e; /使能信号output lcd_rs; /指令、数据选择output lcd_rw; /读、写选择output SEL0; /LCD1602读写选择output SEL1; / LCD1602读写选择output SEL2; / LCD1602读写选择wire 10:0 tone; /分频预置数-跟音调相匹wire 4:0 toneindex; /音符reg clk4hz;reg 24:0 cnt1; /计数器reg 24:0 cnt2; /计数器always (posedge
12、clk) begin if(cnt2=25b101111101011110000100000) begin clk4hz=clk4hz; /对50MHz进行4Hz分频 cnt2=25b0; end else begin cnt2 = cnt2 + 1b1; end endjianpu u1(.sel(song_sel),.clk(clk4hz),.toneindex(toneindex);zhuanhuan u2(.index(toneindex),.tone(tone),.ledpos(ledpos),.ledneg(ledneg),.sms(sms),.smb(smb);fenpin u3
13、(.clk(clk),.tone(tone),.spks(spkout);lcd1602 u4(.clk(clk),.rst_n(rst_n),.lcd_data(lcd_data),.lcd_e(lcd_e),.lcd_rs(lcd_rs),.lcd_rw(lcd_rw),.SEL0(SEL0),.SEL1(SEL1),.SEL2(SEL2),.sel(song_sel);endmodule (2)fenpin模块程序设计module fenpin(clk,tone,spks);input clk;input 10:0 tone; /分频预置数-跟音调相匹配output reg spks;
14、/声音输出reg preclk,fullspks;always(posedge clk) begin reg 3:0 count4; preclk49) begin preclk=1; /将clk进行50分频 count4=0; end else count4=count4+1; endalways(posedge preclk) begin reg 10:0 count11; /11位可预置计数器 if(count11=11h7FF) begin count11=tone; fullspks=1; /按照预置数进行分频 end else begin count11=count11+1; fu
15、llspks=0; end endalways(posedge fullspks) begin reg count2; count2=count2; if(count2=1) spks=1; /将输出再次2分频,展宽脉冲,使 扬声器有足够功率发音 else spks=0; endendmodule(3)zhuanhuan模块程序设计module zhuanhuan(index,sms,smb,ledpos,ledneg,tone);input 4:0 index; /音符output reg 7:0 sms; /数码管段选,用于显示简谱output reg 7:0 smb; /数码管位选,用于
16、显示简谱output reg 1:0 ledpos; /发光二极管阳极,用于区分低、中、 高音output reg 3:0 ledneg; /发光二极管阴极,用于区分低、中、 高音output reg 10:0 tone; /分频预置数-跟音调相匹配reg 3:0 code;always(index) begin case(index) /将简谱音符与分频预置数相匹配 5b00000: tone=11b11111111111; 5b00001: tone=11d137; 5b00010: tone=11d345; 5b00011: tone=11d531; 5b00100: tone=11d6
17、16; 5b00101: tone=11d773; 5b00110: tone=11d912; 5b00111: tone=11d1036; 5b01000: tone=11d1092; 5b01001: tone=11d1197; 5b01010: tone=11d1290; 5b01011: tone=11d1332; 5b01100: tone=11d1410; 5b01101: tone=11d1480; 5b01110: tone=11d1542; 5b01111: tone=11d1570; 5b10000: tone=11d1622; 5b10001: tone=11d1668;
18、 5b10010: tone=11d1690; 5b10011: tone=11d1728; 5b10100: tone=11d1764; 5b10101: tone=15) begin temp=index+2; code=1b0,temp2:0; ledpos=8) begin temp=index+1; code=1b0,temp2:0; ledpos=temp4:3; /中音显示 end else begin temp=index; code=1b0,temp2:0; ledpos=88) counter=8d0; else counter=128) counter=8d0; else
19、 counter=190) counter=8d0; else counter=416) counter=8d0; else counter=counter+1; end endmusic u1(.address(counter),.q(toneindex1),.clock(clk);laohu u2(.address(counter),.q(toneindex2),.clock(clk);tiankong u3(.address(counter),.q(toneindex3),.clock(clk);gaosuni u4(.address(counter),.q(toneindex4),.c
20、lock(clk);always(*) case(sel) 2b00:toneindex=toneindex1; /选择第一首歌低、中、高音依 次循环 2b01:toneindex=toneindex2; /选择第二首歌两只老虎 2b10:toneindex=toneindex3; /选择第三首歌天空之城 2b11:toneindex=toneindex4; /选择第四首歌快点告诉你 default:; endcase endmodule(5)lcd1602模块程序设计module lcd1602(clk,rst_n,lcd_data,lcd_e,lcd_rs,lcd_rw,SEL0,SEL1
21、,SEL2,sel); input clk; / 50MHz时钟 input rst_n; / 复位信号 input 1:0 sel; output reg 7:0 lcd_data; / 数据总线 output lcd_e; / 使能信号 output reg lcd_rs; / 指令、数据选择 output lcd_rw; / 读、写选择 output SEL0; / LCD1602读写选择 output SEL1; / LCD1602读写选择 output SEL2; / LCD1602读写选择reg 127:0 row1_val ;always(sel)begin case(sel)
22、2b00: row1_val=gao zhong di yin; 2b01: row1_val=liang zhi lao hu; 2b10: row1_val=tiankongzhicheng; 2b11: row1_val=kuaidiangaosuni ; default:; endcaseendassign SEL0 = 1b0; assign SEL1 = 1b0; assign SEL2 = 1b1; / 分频模块 开始reg 15:0 cnt; / 计数子always (posedge clk, negedge rst_n) if (!rst_n) cnt = 0; else c
23、nt = cnt + 1b1;wire lcd_clk = cnt15; / 分频模块 结束/ LCD1602驱动模块 开始parameter IDLE = 8h00;/ 写指令,初始化parameter DISP_SET = 8h01; / 显示模式设置parameter DISP_OFF = 8h03; / 显示关闭parameter CLR_SCR = 8h02; / 显示清屏parameter CURSOR_SET1 = 8h06; / 显示光标移动设置parameter CURSOR_SET2 = 8h07; / 显示开及光标设置/ 显示第一行parameter ROW1_ADDR
24、= 8h05; / 写第1行起始地址parameter ROW1_0 = 8h04;parameter ROW1_1 = 8h0C;parameter ROW1_2 = 8h0D;parameter ROW1_3 = 8h0F;parameter ROW1_4 = 8h0E;parameter ROW1_5 = 8h0A;parameter ROW1_6 = 8h0B;parameter ROW1_7 = 8h09;parameter ROW1_8 = 8h08;parameter ROW1_9 = 8h18;parameter ROW1_A = 8h19;parameter ROW1_B =
25、 8h1B;parameter ROW1_C = 8h1A;parameter ROW1_D = 8h1E;parameter ROW1_E = 8h1F;parameter ROW1_F = 8h1D;/ 显示第二行reg 5:0 current_state, next_state; / 现态、次态/ FSM: always1always (posedge lcd_clk, negedge rst_n) if(!rst_n) current_state = IDLE; else current_state = next_state;/ FSM: always2alwaysbegin case(current_state) IDL
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1