基于单片机的电子琴课程设计Word格式.docx
《基于单片机的电子琴课程设计Word格式.docx》由会员分享,可在线阅读,更多相关《基于单片机的电子琴课程设计Word格式.docx(18页珍藏版)》请在冰点文库上搜索。
高音1
高音2
高音3
高音4
高音5
高音6
高音7
频率/HZ
522
587
659
700
780
880
988
延时参数
63
56
50
47
42
37
33
音长参数
65
73
82
88
98
110
124
音阶代码
21
22
23
24
25
26
27
中音1
中音2
中音3
中音4
中音5
中音6
中音7
262
294
330
349
392
440
494
126
113
100
95
85
75
67
41
44
49
55
62
11
12
13
14
15
16
17
低音1
低音2
低音3
低音4
低音5
低音6
低音7
131
147
165
175
196
220
247
254
226
201
190
170
150
134
18
28
31
01
02
03
04
05
06
07
特殊功能
休止符
重复演奏
停止演奏
简谱
00
40
255
(1)DO的频率为262HZ,所以
周期T=1/f=1/262s=3816μs
半周期t=T/2=1908μs
(2)若以程序:
MOVR6,#DATA;
1周
ACALLDELAY;
2周
共需耗时3个机器周期,即耗时1μs×
3=3μs
DELAY:
MOVB,R6;
需耗时2个机器周期,即耗时1μs×
2=2μs
DL:
MOVR7,#6;
DJNZR7,$;
DJNZR6,DL;
此循环部分,每执行一次共需耗时15个机器周期,即耗时1μs×
15=15μs
MOVR6,B;
2周
RET;
共需耗时4机器周期,即耗时1μs×
4=4μs
来达成延时t的目的,则因t=1908μs,且
MOVR6,#DATA
ACALLDELAY
MOVB,R6
MOVR6,B
RET
这5个指令共耗时9μs,所以在DELAY子程序中,循环的部分只能是:
1908μs-9μs=1899μs
(3)循环的部分每执行一次耗时15μs,故要延时1899μs需要执行126次,即R6=126
就可产生所需DO音调。
其他音调所需的R6值,算法相同。
(4)实际上,做电子琴时,程序必须不断地判断是哪一个键被按下,所以程序中还有其他的指令在消耗时间。
因此实际采用的R6的值应该比上述计算值少一点点,音阶才会正确。
但是要把R6的值计算很准确,实在很费时间,况且判断按键的状态所耗时间与周期T比起来实在微不足道,所以在设计程序时只采用上述计算方法计算R6的值即可,程序在判断是哪个键被按下所耗费的时间可忽略不计。
3.音乐产生的原理:
由于一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的延时时间产生这样的方波频率信号。
除了音符以外,节拍也是音乐的关键组成部分,节拍实际上就是音持续时间的长短,在单片机系统中可以用延时时间的长短来实现,如果1/4拍的延时时间是0.4秒,则1拍的延时时间就是1.6秒,只要知道1/4拍的延时时间,其余的
节拍就是它的倍数。
如果单片机要自己播放音乐,那么就必须在程序中考虑到节拍的设置。
为了编写计算机乐谱的方便,所以我们自己定义了音阶代码,例如用01代表低音DO,用11代表中音DO,用21代表高音DO,如表1所列。
另外,我们用40代表重复演奏,用255代表停止演奏。
在程序中编写计算机乐谱时,就是用这些音阶代码来代替各音阶。
音阶代码可岁曲子的节奏快慢有自己决定,例如1拍定位04(就是音长的4倍),半拍就是02,2拍就是08,以此类推。
各音拍的音拍代码如表2所列。
表2各音拍的音拍代码
音拍
1/4拍
1/2拍
3/4拍
1拍
11/4拍
11/2拍
13/4拍
2拍
音拍代码
08
21/4拍
21/2拍
23/4拍
3拍
31/4拍
31/2拍
33/4拍
4拍
09
10
41/4拍
41/2拍
43/4拍
5拍
51/4拍
51/2拍
53/4拍
6拍
19
20
把乐谱改编为程序中的计算机乐谱时,必须按照“音阶代码在前,音拍代码在后”的规则排列,乐谱结束时,必须以40(表示重复演奏)或255(表示只演奏一遍就停止)作结尾。
4.程序流程图:
5.程序:
ORG0000H
MOVP2,#B
MOVP3,#B
TEST:
JNBP2.0,DO1;
P2.0=0吗?
JNBP2.1,RE1;
P2.1=0吗?
JNBP2.2,MI1;
P2.2=0吗?
JNBP2.3,FA1;
P2.3=0吗?
JNBP2.4,SO1;
P2.4=0吗?
JNBP2.5,LA1;
P2.5=0吗?
JNBP2.6,SI1;
P2.6=0吗?
JNBP2.7,DOH1;
P2.7=0吗?
JNBP3.0,START;
P3.0=0吗?
AJMPTEST
DO1:
MOVR6,#126
AJMPOUTPUT1
RE1:
MOVR6,#113
MI1:
MOVR6,#100
FA1:
MOVR6,#95
SO1:
MOVR6,#85
LA1:
MOVR6,#75
SI1:
MOVR6,#67
DOH1:
MOVR6,#63
AJMPOUTPUT1
OUTPUT1:
CLRP3.7;
令扬声器通电
ACALLDELAY;
延时半周期t
SETBP3.7;
令扬声器断电
AJMPTEST;
重新测试按键
START:
MOVDPTR,#MUSIC;
DPTR指向乐谱的开头
CONT:
CLRA;
读取乐谱内的音阶代码
MOVCA,@A+DPTR;
A=音阶代码
CJNEA,#40,CHK;
若音阶代码为40
AJMPSTART;
则从头开始演奏
STOP:
MOVA,#255;
若音阶代码为255
则停止演奏
CHK:
PUSHACC;
保存A的内容
INCDPTR
CLRA;
读取乐谱内的音拍代码
MOVCA,@A+DPTR
MOVR4,A;
R4=音拍代码
POPACC;
取回A的内容
CHK1:
CJNEA,#01,CHK2;
若音阶代码为01,
ACALLDOL;
则产生低音DO的声音
JNBP3.2,STOP;
若P3.2=0,则停止演奏
CHK2:
CJNEA,#02,CHK3;
若音阶代码为02,
ACALLREL;
则产生低音RE的声音
CHK3:
CJNEA,#03,CHK4;
若音阶代码为03,
ACALLMIL;
则产生低音MI的声音
CHK4:
CJNEA,#04,CHK5;
若音阶代码为04,
ACALLFAL;
则产生低音FA的声音
CHK5:
CJNEA,#05,CHK6;
若音阶代码为05,
ACALLSOL;
则产生低音SO的声音
若P3.2=0,则停止演奏
CHK6:
CJNEA,#06,CHK7;
若音阶代码为06,
ACALLLAL;
则产生低音LA的声音
CHK7:
CJNEA,#07,CHK11;
若音阶代码为07,
ACALLSIL;
则产生低音SI的声音
CHK11:
CJNEA,#11,CHK12;
若音阶代码为11,
ACALLDO;
则产生中音DO的声音
CHK12:
CJNEA,#12,CHK13;
若音阶代码为12,
ACALLRE;
则产生中音RE的声音
CHK13:
CJNEA,#13,CHK14;
若音阶代码为13,
ACALLMI;
则产生中音MI的声音
CHK14:
CJNEA,#14,CHK15;
若音阶代码为14,
ACALLFA;
则产生中音FA的声音
CHK15:
CJNEA,#15,CHK16;
若音阶代码为15,
ACALLSO;
则产生中音SO的声音
CHK16:
CJNEA,#16,CHK17;
若音阶代码为16,
ACALLLA;
则产生中音LA的声音
CHK17:
CJNEA,#17,CHK21;
若音阶代码为17,
ACALLSI;
则产生中音SI的声音
CHK21:
CJNEA,#21,CHK22;
若音阶代码为21,
ACALLDOH;
则产生高音DO的声音
CHK22:
CJNEA,#22,CHK23;
若音阶代码为22,
ACALLREH;
则产生高音RE的声音
CHK23:
CJNEA,#23,CHK24;
若音阶代码为23,
ACALLMIH;
则产生高音MI的声音
CHK24:
CJNEA,#24,CHK25;
若音阶代码为24,
ACALLFAH;
则产生高音FA的声音
CHK25:
CJNEA,#25,CHK26;
若音阶代码为25,
ACALLSOH;
则产生高音SO的声音
CHK26:
CJNEA,#26,CHK27;
若音阶代码为26,
ACALLLAH;
则产生高音LA的声音
CHK27:
CJNEA,#27,CHK0;
若音阶代码为27,
ACALLSIH;
则产生高音SI的声音
CHK0:
CJNEA,#00,CONT2;
若音阶代码为00,
ACALLNON;
则不发出声音
CONT2:
INCDPTR;
继续读取乐谱
AJMPCONT
DOL:
MOVR6,#254;
R6=延时参数
MOVR5,#16;
R5=音长参数
AJMPOUTPUT;
设定低音DO的相对参数
REL:
MOVR6,#226;
设定低音RE的相应参数
MOVR5,#18
AJMPOUTPUT
MIL:
MOVR6,#201;
设定低音MI的相应参数
MOVR5,#21
FAL:
MOVR6,#190;
设定低音FA的相对参数
MOVR5,#22
SOL:
MOVR6,#170;
设定低音SO的相应参数
MOVR5,#25
LAL:
MOVR6,#150;
设定低音LA的相应参数
MOVR5,#28
SIL:
MOVR6,#134;
设定低音SI的相应参数
MOVR5,#31
DO:
MOVR6,#126;
设定中音DO的相对参数
MOVR5,#33
RE:
MOVR6,#113;
设定中音RE的相对参数
MOVR5,#37
MI:
MOVR6,#100;
设定中音MI的相对参数
MOVR5,#41
FA:
MOVR6,#95;
设定中音FA的相对参数
MOVR5,#44
SO:
MOVR6,#85;
设定中音SO的相对参数
MOVR5,#49
LA:
MOVR6,#75;
设定中音LA的相对参数
MOVR5,#55
SI:
MOVR6,#67;
设定中音SI的相对参数
MOVR5,#62
DOH:
MOVR6,#63;
设定高音DO的相应参数
MOVR5,#65
REH:
MOVR6,#56;
设定高音RE的相应参数
MOVR5,#73
MIH:
MOVR6,#50;
设定高音MI的相应参数
MOVR5,#82
FAH:
MOVR6,#47;
设定高音FA的相应参数
MOVR5,#88
SOH:
MOVR6,#42;
设定高音SO的相应参数
MOVR5,#98
LAH:
MOVR6,#37;
设定高音LA的相应参数
MOVR5,#110
SIH:
MOVR6,#33;
设定高音SI的相应参数
MOVR5,#124
NON:
设定休止符相应参数
MOVR5,#124
AJMPOUTPUT
OUTPUT:
MOVACC,R5;
保存R5的内容
LOOP:
CJNEA,#00,SOUND;
若音阶代码为00,则不让扬声器通电
LJMPMUTE
SOUND:
CLRP3.7;
MUTE:
ACALLDELAY;
延时半周期
SETBP3.7;
ACALLDELAY;
DJNZR5,LOOP;
输出一个音长,共R5周的方波
MOVR5,ACC;
取回R5的内容
DJNZR4,OUTPUT;
一共输出R4个音长
REST:
静音
MOVR5,#20
WAIT:
DJNZR5,WAIT
MOVB,R6;
延时半周期t=15μs×
R6+9μs
MOVR7,#6
DJNZR7,$
DJNZR6,DL
MOVR6,B
RET
MUSIC:
DB11,04,11,04,11,04
DB13,06,12,02,11,04
DB13,04,13,04,13,04
DB15,06,14,02,13,04
DB15,04,14,04,13,04
DB12,08,00,04
DB12,08,11,02,07,02
DB11,04,12,04,13,04
DB14,08,13,02,12,02
DB13,04,14,04,15,04
DB15,02,14,02,13,04,12,04
DB11,08,00,04
DB40;
END
五、心得与体会
这次设计从软件方面来讲不是很难,程序相对长一点,但都是书本上所学的知识,主要是中端及其服务程序的编写。
在protues上仿真,则起到很好的效果,因为元器件都是理想状态的,但做出实物来却没有那么简单啦。
经过多次调试、修改才得以出结果。
经过本次课程设计,我们比较好的把理论知识与实践相结合,而我们在也本次设计中收获不少。
最重要的是在实践中理解了书本上的知识,明白了学以致用的真谛,明白做好一件事单靠自己是不够的,集体团队精神也非常重要。
也明白老师为什么要求我们做好这个课程的原因。
他是为了教会我们如何运用所学的知识去解决实际问题,提高我们的动手能力。
设计过程中,首先,对于汇编语言多了一层了解,其次,还有硬件的接线,还有8051芯片的引脚方面,都让我们收获不少。
加强了自身的动手能力。
六、参考文献
1.单片机原理与接口技术(第二版)李晓林、牛昱光、闫高伟主编,电子工业出版社。