#include<reg52.h>
#include<intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
sbit buzzer = P2 ^ 5; //蜂鳴器管腳
u8 time0h = 0; //定時器高8位
u8 time0l = 0; //定時器低8位
u8 bats = 0; //延時拍數
bit stop = 0; //是否為休止符,0是,1不是(給stop賦值為非0則stop等于1)
bit smooth = 0; //1圓滑,0不圓滑
code u8 node[] = {
//0xf2,0xf3,0xf5,0xf5,0xf6,0xf7,0xf8,//C調低音高8位 @11.0592MHz
//0xf9,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,//C調中音
//0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,//C調高音
//0x42,0xc1,0x17,0xaf,0xd1,0xd1,0xb6,//C調低音低8位
//0x1e,0xde,0x8a,0xd8,0x68,0xe9,0x5b,
//0x8f,0xf0,0x45,0x69,0xb4,0xf4,0x2e,
//0xf3,0xf5,0xf6,0xf6,0xf7,0xf8,0xf9,//D調
//0xf9,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,
//0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,
//0xc1,0x17,0x45,0xd1,0xd1,0xb6,0x80,
//0xde,0x8a,0x23,0x68,0xe9,0x5b,0xc1,
//0xf0,0x45,0x91,0xb4,0xf4,0x2e,0x78,
//0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,//E調
//0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfd,
//0xfd,0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,
//0x17,0x45,0x53,0xd1,0xb6,0x80,0x36,
//0x8a,0x23,0xab,0xe9,0x5b,0xc1,0x1c,
//0x45,0x91,0xd5,0xf4,0x2e,0x78,0xa3,
//0xf5,0xf6,0xf7,0xf8,0xf9,0xf9,0xfa,//F調
//0xfa,0xfb,0xfb,0xfc,0xfc,0xfc,0xfd,
//0xfd,0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,
//0xaf,0xd1,0xd1,0x46,0x1e,0xde,0x8a,
//0xd8,0x68,0xe9,0x23,0x8f,0xf0,0x45,
//0x69,0xb4,0xf4,0x12,0x60,0x8e,0xb6,
//0xf6,0xf7,0xf8,0xf9,0xf9,0xfa,0xfb,//G調
//0xfb,0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,
//0xfd,0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,
//0xd1,0xd1,0xb6,0x1e,0xde,0x8a,0x23,
//0x69,0xe9,0x5b,0x8f,0xf0,0x45,0x91,
//0xb4,0xf4,0x2e,0x60,0x8e,0xb6,0xea,
0xf7,0xf8,0xf9,0xf9,0xfa,0xfb,0xfb,//A調
0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,
0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xff,
0xd1,0xb6,0x80,0xde,0x8a,0x23,0xab,
0xe9,0x5b,0xc1,0xf0,0x45,0x91,0xd5,
0xf4,0x2e,0x78,0x8e,0xb6,0xea,0x09
//0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,//B調
//0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,
//0xfe,0xfe,0xfe,0xfe,0xfe,0xff,0xff,
//0xb6,0x80,0x36,0x8a,0x23,0xab,0x23,
//0x5b,0xc1,0x1c,0x45,0x91,0xd5,0x12,
//0x2e,0x78,0xa3,0xb6,0xea,0x09,0x23
};
code u8 music[] = {
0,1,2,0, 3,1,2,0, 3,1,2,0, 6,1,1,0, 6,1,1,1, 6,1,2,0, 1,1,2,0, 2,1,2,0,
3,1,1,0, 3,1,1,1, 3,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,2,0,
3,1,2,0, 6,1,2,0, 6,1,3,0, 5,1,1,0, 5,1,3,0, 4,1,1,1, 4,1,1,0, 3,1,3,1,
3,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,2,0, 3,1,2,0, 6,1,2,1, 6,1,2,0,
1,1,2,0, 2,1,2,0, 3,1,6,0, 0,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,2,0,
3,1,2,0, 1,1,2,0, 3,1,2,0, 3,1,1,0, 4,1,1,1, 4,1,2,0, 3,1,2,0, 1,1,8,0,
0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,2,0, 3,1,2,0, 6,1,1,0, 6,1,1,1, 6,1,2,0,
1,1,2,0, 2,1,2,0, 3,1,1,0, 3,1,1,1, 3,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,4,0,
0,1,2,0, 3,1,2,0, 3,1,2,0, 6,1,2,0, 6,1,3,0, 5,1,1,0, 5,1,3,0, 4,1,1,1,
4,1,1,0, 3,1,3,1, 3,1,4,0, 0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,1,0, 3,1,1,0,
3,1,2,0, 6,1,2,1, 6,1,2,0, 1,1,2,0, 2,1,2,0, 3,1,2,1, 3,1,4,0, 0,1,4,0,
0,1,4,0, 0,1,4,0, 0,1,2,0, 3,1,2,0, 3,1,2,0, 1,1,2,0, 3,1,2,0, 3,1,1,0,
4,1,1,1, 4,1,2,0, 3,1,2,0, 1,1,8,0, 0,1,2,0, 5,1,2,0, 6,1,2,0, 7,1,2,0,
1,2,2,0, 7,1,1,0, 1,2,1,1, 1,2,2,0, 5,1,1,0, 6,1,1,0, 6,1,4,0, 5,1,2,0,
4,1,1,0, 4,1,1,1, 4,1,2,0, 3,1,2,0, 3,1,2,0, 3,1,1,0, 2,1,1,1, 2,1,2,0,
5,1,2,0, 6,1,2,0, 7,1,2,0, 1,2,2,0, 7,1,1,0, 1,2,1,1, 1,2,2,0, 5,1,1,0,
6,1,1,0, 6,1,4,0, 6,1,2,0, 7,1,1,0, 1,2,1,1, 1,2,2,0, 1,2,2,0, 1,2,2,0,
1,2,1,0, 2,2,1,1, 2,2,2,0, 0,1,1,0, 5,1,1,0, 6,1,2,0, 7,1,2,0, 1,2,2,0,
7,1,1,0, 1,2,1,1, 1,2,2,0, 3,2,2,0, 6,2,3,0, 5,2,1,1, 5,2,2,0, 4,2,2,0,
3,2,4,0, 3,2,2,0, 2,2,2,1, 2,2,4,0, 6,1,2,0, 7,1,2,0, 1,2,4,0, 1,2,2,0,
2,2,1,0, 1,2,1,1, 1,2,3,0, 1,2,1,0, 7,1,2,0, 1,2,1,0, 2,2,1,1, 2,2,4,0,
1,2,2,0, 7,1,2,0, 1,2,8,0, 0,1,0,0
};//歌譜格式為:音符(0-7)+低中高音(0-2)+拍數(單位0.25拍)+是否圓滑(1,0)(最后四位中的第一第三位為終止參數)
void time0() interrupt 1
{
TR0 = 0; //定時器關后賦值,防止從0開始定時
buzzer = !buzzer;
TH0 = time0h;
TL0 = time0l;
TR0 = 1; //定時器開
}
void Delayms(u16 ms)//延時ms毫秒
{
while (ms--)
{
u8 i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void Sing()
{
if (stop)
{
TH0 = time0h;
TL0 = time0l;
TR0 = 1;
}
else
TR0 = 0;
Delayms(200*bats); //72拍/min
if (!smooth)
{
TR0 = 0;
Delayms(10); //音符間間歇
TR0 = 1;
}
}
void main()
{
u16 i = 0;
u8 j = 0;
EA = 1; //總中斷開
ET0 = 1; //T0中斷允許
TMOD = 1; //工作方式1,16位定時計數器
while (1) //控制播放次數
{
i = 0;
while (music[ i] != 0 || music[i + 2] != 0)//這里定義音符為0與拍數為0組合代表結束歌曲
{
j = music[ i] + 7 * music[i + 1] - 1; //確定音符高8位位置
time0h = node[j];
time0l = node[j+21];
bats = music[i + 2];
stop = music[ i];
smooth = music[i + 3];
Sing();
i += 4;
}
}
}
/*下面是兩個神秘樂譜*/
//樂譜1
/*6,1,6,0, 5,1,2,0, 3,1,4,0, 5,1,4,0, 1,2,4,0, 6,1,2,1, 5,1,2,0, 6,1,8,0,
3,1,4,0, 5,1,2,0, 6,1,2,0, 5,1,4,0, 3,1,2,1, 2,1,2,0, 1,1,2,1, 6,0,2,0,
5,1,2,1, 3,1,2,0, 2,1,8,0, 2,1,6,0, 3,1,2,0, 5,1,4,0, 5,1,2,0, 6,1,2,0,
3,1,6,1, 2,1,2,0, 1,1,8,0, 5,1,6,0, 3,1,2,0, 2,1,2,1, 1,1,2,0, 6,0,2,1,
1,1,2,0, 5,0,8,0, 0,1,0,0
*/
//樂譜2
/*1,1,4,0, 2,1,4,0, 3,1,4,0, 1,1,4,0, 1,1,4,0, 2,1,4,0, 3,1,4,0, 1,1,4,0,
3,1,4,0, 4,1,4,0, 5,1,8,0, 3,1,4,0, 4,1,4,0, 5,1,8,0, 5,1,3,0, 6,1,1,0,
5,1,3,0, 4,1,1,0, 3,1,4,0, 1,1,4,0, 5,1,3,0, 6,1,1,0, 5,1,3,0, 4,1,1,0,
3,1,4,0, 1,1,4,0, 1,1,4,0, 5,0,4,0, 1,1,8,0, 1,1,4,0, 5,0,4,0, 1,1,8,0,
0,1,0,0
*/
|