PLD课程设计音乐播放.docx
- 文档编号:5746430
- 上传时间:2022-12-31
- 格式:DOCX
- 页数:28
- 大小:47.57KB
PLD课程设计音乐播放.docx
《PLD课程设计音乐播放.docx》由会员分享,可在线阅读,更多相关《PLD课程设计音乐播放.docx(28页珍藏版)》请在冰豆网上搜索。
PLD课程设计音乐播放
成绩
中国农业大学
课程论文
(2011-2012学年夏季学期)
论文题目:
基于VerilogHDL的音乐
播放器设计
课程名称:
PLD课程设计
任课教师:
薛一鸣
班 级:
电子091
学 号:
0908140818
姓 名:
宋艳
基于VerilogHDL的音乐播放器设计
1设计目的2
2设计任务2
3系统设计3
3.1乐曲演奏部分3
3.1.1音调的控制3
3.1.2音长的控制4
3.2键盘扫描部分8
3.3数码管动态显示部分12
3.4LCD显示部分14
4心得体会17
摘要:
本实验主要在理论分析和具体的软件实现上,完成一个简易的音乐播放器,可以完成上一曲,下一曲,循环播放,暂停和液晶显示,同时还增加了手动按键编曲播放功能。
在理论分析的基础上,用VerilogHDL语言编写源代码,再配合具体电路连接,实现对蜂鸣器振动的控制,以及对各项显示功能的切换控制等。
关键字:
Verilog频率显示音乐播放
1设计目的
1)学习VerilogHDL的设计技巧,掌握乐曲演奏电路的工作原理;
2)学习音符与频率关系,了解怎样控制音调的高低变化和音长,从而完成乐曲的自动循环演奏;
3)学习音频功放模块接口特点;
4)培养自主学习、正确分析和解决问题的能力。
2设计任务
1、使用VerilogHDL设计乐曲演奏电路,系统实现是用硬件描述语言VerilogHDL按分频控制的方式进行设计,然后进行编程电路功能验证,奏出美妙的乐曲。
2、通过控制输出到扬声器的激励信号频率的高低和持续的时间,从而使扬声器发出连续的乐曲声,且当乐曲演奏完成时,保证能自动从头开始演奏。
3、简易乐曲播放器可以实现的功能:
1)播放器内预存4首乐曲;
2)顺序播放:
按内部给定的顺序依次播放3首乐曲,每首歌曲可以循环播放;
3)用三位数码管显示输出相应的高中低音符,并用一个数码管显示当前播放乐曲的顺序号,实现动态显示;
4)设置开始键和暂停键,乐曲播放过程中按暂停键则暂停播放,再按开始键则继续播放;
5)设置Next和Previous键,按Next键可以听下一首,按Previous键可以听上一首;
6)实现手动发音,就是按键发出特定的音符;
7)用LCD显示正在播放的歌曲名称,并显示下一首歌曲名称;
8)在音乐播放的同时,会有led流水灯的闪烁,以及LED矩阵的闪烁。
3系统设计
3.1乐曲演奏部分
乐曲演奏的原理是这样的:
组成乐曲的每个音符的频率值(音调)及其持续的时间(音长)是乐曲能连续演奏所需的两个基本数据,因此只要控制输出到扬声器的激励信号频率的高低和持续的时间,就可以使扬声器发出连续的乐曲声。
3.1.1音调的控制
频率的高低决定了音调的高低。
音乐的十二平均率规定:
每两个8度音(如简谱中的中音1与高音1)之间的频率相差一倍。
在两个8度音之间,又可分为12个半音,每两个半音的频率比为12√2。
另外,音名A(简谱中的低音6)的频率为440Hz,音名B到C之间、E到F之间为半音,其余为全音。
由此可以计算出简谱中从低音1至高音1之间每个音名对应的频率,如表3.11所示:
表3.11简谱中的音名与频率的关系
音名
频率/Hz
音名
频率/Hz
音名
频率/Hz
低音1
261.63
中音1
523.25
高音1
1045.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.00
中音6
880.00
高音6
1760.00
低音7
493.88
中音7
987.76
高音7
1975.52
所有不同频率的信号都是从同一个基准频率分频得到的。
由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。
若基准频率过低,则由于分频比太小,四舍五入取整后的误差较大;若基准频率过高,虽然误差变小,但分频数将变大。
实际的设计综合考虑这两方面的因素,在尽量减小频率误差的前提下取合适的基准频率。
本例中选取1MHz为基准频率。
实际上,只要各个音名间的相对频率关系不变,演奏出的乐曲听起来都不会“走调”。
各音阶频率及相应的分频比如表2所示。
为了减小输出的偶次谐波分量,最后输出到扬声器的波形应为对称方波,因此在到达扬声器之前,有一个二分频的分频器。
表2中的分频比就是从1MHz频率基础上计算得出的。
由于最大的分频系数为3822,故采用12位二进制计数器分频可满足需要。
在表2中,除给出了分频比以外,还给出了对应于各个音阶频率时计数器不同的预置数。
对于不同的分频系数,只要加载不同的预置数即可。
采用加载预置数实现分频的方法比采用反馈复零法节省资源,实现起来也容易一些,如表3.12所示:
表3.12各音阶频率对应的分频比及预置数
音名
分频比
预置数
音名
分频比
预置数
低音1
3822
273
中音5
1276
2819
低音2
3405
690
中音6
1136
2959
低音3
3034
1061
中音7
1012
3083
低音4
2863
1232
高音1
956
3139
低音5
2551
1544
高音2
851
3244
低音6
2273
1822
高音3
758
3337
低音7
2025
2070
高音4
716
3379
中音1
1911
2184
高音5
638
3457
中音2
1703
2392
高音6
568
3527
中音3
1517
2578
高音7
506
3589
中音4
1432
2663
休止符
0
4095
此外,对于乐曲中的休止符,只要将分频系数设为0,即初始值为4095,即可,此时扬声器将不会发声。
3.1.2音长的控制
音符的持续时间必须根据乐曲的速度及每个音符的节拍数来确定。
本例演奏的梁祝片段,最短的音符为4分音符,如果将全音符的持续时间设为1s的话,则只需要再提供一个4Hz的时钟频率即可产生4分音符的时长。
控制音调通过设置计数器的预置数来实现,预置不同的数值可以使计数器产生不同频率的信号,从而产生不同的音调。
控制音长是通过控制计数器预置数的停留时间来实现的,预置数停留的时间越长,则该音符演奏的时间越长。
每个音符的演奏时间都是0.25s的整数倍,对于节拍较长的音符,如2分音符,在记谱时将该音名连续记录两次即可。
主要程序代码:
assigncarry=(divider==4095);
always@(posedgeclk)
if(cnt1<124999)
cnt1=cnt1+19'b0000_0000_0000_0000_001;
else
begin
cnt1=0;clk_4hz=!
clk_4hz;
end
always@(posedgeclk)
if(cnt2<4999)
cnt2=cnt2+13'b1;
else
begin
cnt2=0;clk_100hz=!
clk_100hz;
end
always@(posedgeclk)
begin
if(carry)
divider<=origin;
else
divider<=divider+12'b00_0000_0000_01;
end
always@(posedgecarry)
begin
speaker<=~speaker;
end
always@(posedgeclk_4hz)
begin
case({high,med,low})//fenpinbi
//low
'b000000000001:
origin<=273;//1
'b000000000010:
origin<=690;//2
'b000000000011:
origin<=1061;//3
'b000000000100:
origin<=1232;//4
'b000000000101:
origin<=1544;//5
'b000000000110:
origin<=1822;//6
'b000000000111:
origin<=2070;//7
//med
'b000000010000:
origin<=2184;//1
'b000000100000:
origin<=2392;//2
'b000000110000:
origin<=2578;//3
'b000001000000:
origin<=2663;//4
'b000001010000:
origin<=2819;//5
'b000001100000:
origin<=2959;//6
'b000001110000:
origin<=3083;//7
//high
'b000100000000:
origin<=3139;//1
'b000100000000:
origin<=3244;//2
'b000100000000:
origin<=3337;//3
'b000100000000:
origin<=3379;//4
'b000100000000:
origin<=3457;//5
'b000100000000:
origin<=3527;//6
'b000100000000:
origin<=3589;//7
//xiuzhifu
'b000000000000:
origin<=4095;//xiuzhifu
endcase
end
always@(posedgeclk_4hz)
begin
if(counter2==63)
counter2<=0;
else
counter2<=counter2+1;
case(counter2)
0:
{high,med,low}<='b000000000011;
1:
{high,med,low}<='b000000000011;
2:
{high,med,low}<='b000000000011;
3:
{high,med,low}<='b000000000011;
4:
{high,med,low}<='b000000000101;
5:
{high,med,low}<='b000000000101;
6:
{high,med,low}<='b000000000101;
7:
{high,med,low}<='b000000000110;
8:
{high,med,low}<='b000000010000;
9:
{high,med,low}<='b000000010000;
10:
{high,med,low}<='b000000010000;
11:
{high,med,low}<='b000000100000;
12:
{high,med,low}<='b000000000110;
13:
{high,med,low}<='b000000010000;
14:
{high,med,low}<='b000000000101;
15:
{high,med,low}<='b000000000101;
16:
{high,med,low}<='b000001010000;
17:
{high,med,low}<='b000001010000;
18:
{high,med,low}<='b000001010000;
19:
{high,med,low}<='b000100000000;
20:
{high,med,low}<='b000001100000;
21:
{high,med,low}<='b000001010000;
22:
{high,med,low}<='b000000110000;
23:
{high,med,low}<='b000001010000;
24:
{high,med,low}<='b000000100000;
25:
{high,med,low}<='b000000100000;
26:
{high,med,low}<='b000000100000;
27:
{high,med,low}<='b000000100000;
28:
{high,med,low}<='b000000100000;
29:
{high,med,low}<='b000000100000;
30:
{high,med,low}<='b000000100000;
31:
{high,med,low}<='b000000100000;
32:
{high,med,low}<='b000000100000;
33:
{high,med,low}<='b000000100000;
34:
{high,med,low}<='b000000100000;
35:
{high,med,low}<='b000000110000;
36:
{high,med,low}<='b000000000111;
37:
{high,med,low}<='b000000000111;
38:
{high,med,low}<='b000000000110;
39:
{high,med,low}<='b000000000110;
40:
{high,med,low}<='b000000000101;
41:
{high,med,low}<='b000000000101;
42:
{high,med,low}<='b000000000101;
43:
{high,med,low}<='b000000000110;
44:
{high,med,low}<='b000000010000;
45:
{high,med,low}<='b000000010000;
46:
{high,med,low}<='b000000100000;
47:
{high,med,low}<='b000000100000;
48:
{high,med,low}<='b000000000011;
49:
{high,med,low}<='b000000000011;
50:
{high,med,low}<='b000000010000;
51:
{high,med,low}<='b000000010000;
52:
{high,med,low}<='b000000000110;
53:
{high,med,low}<='b000000000101;
54:
{high,med,low}<='b000000000110;
55:
{high,med,low}<='b000000010000;
56:
{high,med,low}<='b000000000101;
57:
{high,med,low}<='b000000000101;
58:
{high,med,low}<='b000000000101;
59:
{high,med,low}<='b000000000101;
60:
{high,med,low}<='b000000000101;
61:
{high,med,low}<='b000000000101;
62:
{high,med,low}<='b000000000101;
63:
{high,med,low}<='b000000000101;
endcase
end
3.2键盘扫描部分
本设计通过键盘来控制歌曲的播放,音乐播放器所需各种功能按键非常多,一般的独立式键盘输入不能满足要求,本设计采用4×4矩阵键盘,较好满足了设计要求。
此模块负责对输入设备——4×4键盘采用行列式法进行扫描,并定义每个按键的功能,作为其他模块的控制信号。
各按键的功能如下:
0
1
2
3
4
5
6
7
1
上一首
下一首
暂停
开始
手动弹奏
音乐播放
其中(下一首、上一首、暂停、开始)只有在音乐播放功能时使用,音乐播放只在手动弹奏时使用。
主要程序代码:
always@(posedgeclk_100hz)
begin
case(state)
0:
begin
x=4'b0000;
if(y!
=4'b1111)state=0;
else
begin
state=1;
end
end
1:
begin
x=4'b0000;
if(y==4'b1111)
begin
state=1;
note<='b0000_0000_0000;
end
else
begin
state=2;
end
end
2:
begin
x=4'b0111;state=3;
end
3:
begin
case(y)
4'b1111:
state=4;
4'b1110:
begin
dout='b00111111;
dledmatrix='b11000000;
dled='b1100000011000000;
state=0;//0
end
4'b1101:
begin
dout='b01100110;
dledmatrix='b10011001;
dled='b1001100110011001;
state=0;//4
note<='b0000_0100_0000;
end
4'b1011:
begin
dout='b10000110;
dledmatrix='b01111001;
dled='b0111100101111001;
state=0;//8
note<='b000100000000;
end
4'b0111:
begin
dout='b00110110;
dledmatrix='b11001001;
dled='b1100100111001001;
state=0;//12
if(k!
=0)
begin
p=k;
k=0;
end
end
endcase
end
4:
begin
x=4'b1011;state=5;
end
5:
begin
case(y)
4'b1111:
state=6;
4'b1110:
begin
dout='b00000110;
dledmatrix='b11111001;
dled<='b1111100111111001;
state=0;//1
note<='b000000010000;
end
4'b1101:
begin
dout='b01101101;
dledmatrix='b10010010;
dled='b1001001010010010;
state=0;//5
note<='b000001010000;
end
4'b1011:
begin
dout='b01101111;
dledmatrix='b10010000;
dled='b1001000010010000;
state=0;//9
end
4'b0111:
begin
dout='b01011110;
dledmatrix='b10100001;
dled='b1010000110100001;
state=0;//13
if(k==0)
k=p;
end
endcase
end
6:
begin
x=4'b1101;state=7;
end
7:
begin
case(y)
4'b1111:
state=8;
4'b1110:
begin
dout='b01011011;
dledmatrix='b10100100;
dled='b1010010010100100;
state=0;//2
note<='b000000100000;
end
4'b1101:
begin
dout='b01111101;
dledmatrix='b10000010;
dled='b1000001010000010;
state=0;//6
note<='b000001100000;
end
4'b1011:
begin
dout='b01110111;
dledmatrix='b10001000;
dled='b1000100010001000;
state=0;//10
if((k<=4)&&(k>=2))
k=k-1;
else
k=4;
end
4'b0111:
begin
dout='b01111001;
dledmatrix='b10000110;
dled='b1000011010000110;
state=0;//14shoudong
q=k
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PLD 课程设计 音乐 播放
![提示](https://static.bdocx.com/images/bang_tan.gif)