-
一、设计目的
利用
8052
单片机结合内部定时器设计一个八音盒,按下单键可以
演奏预先
设置的歌曲旋律。
二、设计要求
其基本
功能为:
1
,使用
LED
显示器来显示目前演奏的歌曲编号;
2
,具有
8
个按键操作来选择演奏哪一首歌曲;
3
p>
,内建
8
首歌曲旋律,按下单键可以演
p>
奏歌曲。
三、设计器材
T89
C52
单片机、
晶振、
八个按键、
p>
二位一体共阳极数码管、
电阻电容若干、
导
线。
四、设计方案及分析
设计思路:
(1)
选择
8052
单片机,通过
T0
定时中断,
并配合
P2.0
引脚输出音频频率。
(2)
P2.0
引脚输出接蜂鸣器。
(3)
通过
P0
口接
LED
。
(4)
P1
口接键盘,输入歌曲号。
音符产生方法:
不同的音调有不同的频率。频率不同,音调也就不同。
利用定时器,
使其工作在模式
1
,
定时中断,
然后控制
P2
.0
引脚的输出每次取反,
就可以在
P
2.0
的引脚输出相应的方波频率。改变计数初值,就改变了频率。定
< br>时器的定时时间等于半个周期,
定时时间到就输出脉冲取反,
重复此过程,
就可
在
P2.0
p>
引脚得到一音频的脉冲。
如:中音
1
的频率
=523HZ
,周期
T=1/523=1912us
;
定时器的定时时间为:
T/2=1912/2us=95
6us
;
计算得
TH0,TL0
的计数初值
THTL=64580
下面是个音符计数初值
音符
THTL
音符编码
低音
5
低音
6
低音
7
中音
1
中音
2
中音
3
中音
4
中音
5
中音
6
中音
7
高音
1
高音
2
高音
3
高音
4
高音
5
节拍产生方法:
0F66FH
0F724H
0F81BH
0F88FH
0F95EH
0FA17H
0FA6BH
0FB08H
0FB92H
0FC0EH
0FC4BH
0FCAFH
0FD0CH
0FD36H
0FD84H
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
音乐中的节拍用延时时间产生
。假设
1/4
拍执行一次延时程序,这
1/2
拍就
执行两次延时程序,所以只要求出
< br>1/4
延时时间,其余的节拍就是他的倍数。为
方便记谱
,将节拍数也进行编码,如下:
节拍编码
1
2
3
4
建立曲谱编码表:
编谱用
8
位编码,高
4
位代表音
符,低
4
位代表节拍。如
5
6
中音
5
,中音
6
,
都是
1/2
p>
拍,则编码为:
82H 92H
节拍
1/4
1/2
3/4
1
程序清单:
#include
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit SPEAK =
P2^0;//
接蜂鸣器管脚
uchar th0_f;
uchar tl0_f;
uchar code SEG[10]={0x3f,0x06,0x5b,0x4f
,0x66,0x6d,0x7d,0x07,0x7f,0x67};
uchar
code jie8[8]={12,14,16,17,19,21,23,24};
/**************************
中断函数
*******************************************/
timer0() interrupt 1
{
}
/********************T0
的值
,
及输出频率对照表
***********
************************/
uchar code
freq[36*2]={
0xA9,0xEF,//00220HZ ,1 //0
0x93,0xF0,//00233HZ ,1#
0x73,0xF1,//00247HZ ,2
0x49,0xF2,//00262HZ ,2#
0x07,0xF3,//00277HZ ,3
0xC8,0xF3,//00294HZ ,4
0x73,0xF4,//00311HZ ,4#
0x1E,0xF5,//00330HZ ,5
0xB6,0xF5,//00349HZ ,5#
0x4C,0xF6,//00370HZ ,6
0xD7,0xF6,//00392HZ ,6#
0x5A,0xF7,//00415HZ ,7
0xD8,0xF7,//00440HZ 1 //12
0x4D,0xF8,//00466HZ 1# //13
0xBD,0xF8,//00494HZ 2 //14
0x24,0xF9,//00523HZ 2# //15
0x87,0xF9,//00554HZ 3 //16
0xE4,0xF9,//00587HZ 4 //17
0x3D,0xFA,//00622HZ 4# //18
0x90,0xFA,//00659HZ 5 //19
TL0=tl0_f;TH0=th0_f;
SPEAK =~SPEAK;
//
取反音乐输出
IO
};
0xDE,0xFA,//00698HZ 5# //20
0x29,0xFB,//00740HZ 6 //21
0x6F,0xFB,//00784HZ 6# //22
0xB1,0xFB,//00831HZ 7 //23
0xEF,0xFB,//00880HZ `1
0x2A,0xFC,//00932HZ `1#
0x62,0xFC,//00988HZ `2
0x95,0xFC,//01046HZ `2#
0xC7,0xFC,//01109HZ `3
0xF6,0xFC,//01175HZ `4
0x22,0xFD,//01244HZ `4#
0x4B,0xFD,//01318HZ `5
0x73,0xFD,//01397HZ `5#
0x98,0xFD,//01480HZ `6
0xBB,0xFD,//01568HZ `6#
0xDC,0xFD,//01661HZ `7 //35
/***************************
音乐符号串解释函数
p>
****************************/
//
入口
:
要解释的音乐符号串
,
输出的音调串
,
输
出的时长串
changedata(uchar
*song,uchar *diao,uchar *jie)
{
uchar i,i1,j;
char gaodi; //
高低
+
/-12
音阶
uchar
banyin;//
有没有半个升音阶
uchar
yinchang;//
音长
uchar code
jie7[8]={0,12,14,16,17,19,21,23}; //C
调的
7
个值
*diao=*song;
for(i=0,i1=0;;)
{
gaodi=0;
//
高低
=0
banyin=0;//
半音
=0 <
/p>
yinchang=4;//
音长
1
p>
拍
if((*(song+i)=='|') || (*(song+i)=='
')) i++; //
拍子间隔和一个空格过滤
switch(*(song+i))
{
}
if(*(song+i)==0) //
遇到
0
结束
{
}
j=*(song+i)-0x30; i++;
//
取出基准音
j=jie7[j]+gaodi;
//
加上高低音
yinc:
switch(*(song+i))
{
case '#': //
有半音
j<
/p>
加一个音阶
i++;j++;
goto yinc;
*(diao+i1)=0;
//
加入结束标志
0
*(jie+i1)=0;
return;
case ',':
gaodi=-12;i++;//
低音
break;
case '`':
gaodi=12;i++; //
高音
break;
case '-':
//
有一个音节加长
yinchang+=4;
i++;
goto yinc;
case '_':
//
有一个音节缩短
yinchang/=2;
i++;
}
}
}
goto yinc;
case '.':
//
有一个加半拍
yinchang=yinchang+yinchang/2;
i++;
goto yinc;
*(diao+i1)=j;
//
记录音符
*(jie+i1)=yinchang;
//
记录音长
i1++;
/******************************
奏
乐函数
************************************
***/
//
入口
:
要演奏的音乐符号串
void
play(uchar *songdata)
{
uchar i,c,j=0;
uint n;
uchar
diaodata[48];
//
音调缓冲
uchar
jiedata[48]; //
音长缓冲
changedata(songdata,diaodata,jiedata);
//
解释音乐符号串
TR0=1;
while(P1=0xff)
{
for(i=0;diaodata[i]!=0;i++)
//
逐个符号演奏
{
tl0_f=freq[diaodata[i]*2];
//
取出对应的定时值送给
T0
th0_f=freq[diaodata[i]*2+1];
for(c=0;c
按照音长延时
{
-
-
-
-
-
-
-
-
-
上一篇:国内外丁腈橡胶牌号对比分析
下一篇:分数经典简便运算题