12864的案例我空間案例很多,你可以參考一下。你上面的代碼不適合多首歌曲播放,最好的方式是將音符與節(jié)拍編輯好一起放到一個數(shù)組里,
例如0x11,0x04,
其中0x11中的0x1指的是中音,
(uint16 code FreTab_Low[7]={262,294,330,349,392,440,494}; //低音頻率表
uint16 code FreTab_Mid[7]={523,578,659,698,784,880,988}; //中音頻率表
uint16 code FreTab_Hight[7]={1046,1175,1318,1397,1568,1760,1976}; //高音頻率表),
后一個1指向的是 523HZ,那就是說通過0x11能找到高中低音中的音符,0x04表示節(jié)拍(一種音符延時的長短),那么只要保證數(shù)組指針在++就能取出數(shù)組里的參數(shù),一首歌一個數(shù)組就能擺平。
下面是具體一個例子:
#include<reg51.h>
#define uint8 unsigned char
#define uint16 unsigned int
sbit Music=P2^0;
sbit sw=P3^0;
void DelayMS(uint16 dly)
{
uint16 x,y;
for(x=dly;x>0;x--)
for(y=247;y>0;y--);
}
uint16 code FreTab_Low[7]={262,294,330,349,392,440,494}; //低音頻率表
uint16 code FreTab_Mid[7]={523,578,659,698,784,880,988}; //中音頻率表
uint16 code FreTab_Hight[7]={1046,1175,1318,1397,1568,1760,1976}; //高音頻率表
//大海啊故鄉(xiāng)
uint8 code Happy_Birthday1[]={0x11,0x04,0x12,0x04,0x11,0x0a,0x07,0x02,0x06,0x02,
0x05,0x04,0x13,0x04,0x13,0x0f,0x13,0x04,0x14,0x04,
0x13,0x0a, 0x12,0x02,0x11,0x02,0x06,0x04,0x12,0x04,0x12,0x0f,
0x07,0x04,0x11,0x04,0x07,0x0a,0x06,0x02,0x05,0x02,
0x05,0x04,0x12,0x04,0x12,0x0f,0x14,0x0a,0x13,0x04,0x11,0x04,0x06,0x04,0x11,0x18,
0x15,0x04,0x16,0x04,0x15,0x0a,0x13,0x04,0x15,0x04,0x16,0x04,0x15,0x0f,
0x16,0x04,0x15,0x04,0x14,0x04,0x11,0x02,0x11,0x02,0x16,0x04,0x15,0x04,0x15,0x18,
0x13,0x04,0x14,0x04,0x13,0x0a,0x12,0x02,0x11,0x02,0x06,0x04,0x12,0x04,0x12,0x0f,
0x14,0x04,0x15,0x04,0x14,0x04,0x13,0x04,0x11,0x04,0x06,0x04,
0x11,0x18,0x15,0x04,0x16,0x04,0x15,0x0a,0x13,0x04,0x15,0x04,0x16,0x04,0x15,0x0f,
0x16,0x04,0x15,0x04,0x14,0x04,0x11,0x02,0x11,0x02,0x16,0x04,0x15,0x04,0x15,0x18,
0x13,0x04,0x14,0x04,0x13,0x0a,0x12,0x02,0x11,0x02,
0x06,0x04,0x12,0x04,0x12,0x0f,
0x14,0x04,0x15,0x04,0x14,0x04,0x13,0x04,0x11,0x04,0x06,0x04,0x11,0x18,
0x00,0x00
};
//祝你生日快樂
uint8 code Happy_Birthday2[]={0x11,0x05,0x11,0x05,0x12,0x0a,0x11,0x0a,
0x14,0x0a,0x13,0x14,
0x11,0x05,0x11,0x05,0x12,0x0a,0x11,0x0a,
0x15,0x0a,0x14,0x14,
0x11,0x05,0x11,0x05,0x21,0x0a,0x16,0x0a,
0x14,0x0a,0x13,0x0a,0x22,0x0a,
0x17,0x05,0x17,0x05,0x16,0x0a,0x14,0x0a,
0x15,0x0a,0x14,0x14,0x00,0x00
};
//辣妹子
uint8 code Happy_Birthday3[]={
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x06,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x16,0x04,
0x06,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x06,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x06,0x04,
0x06,0x04,
0x06,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x16,0x04,
0x16,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x13,0x04,
0x13,0x04,
0x06,0x08,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x13,0x02,
0x15,0x02,
0x16,0x04,
0x16,0x04,
0x16,0x08,
0x11,0x04,
0x15,0x02,
0x13,0x02,
0x13,0x02,
0x15,0x02,
0x13,0x04,
0x13,0x04,
0x06,0x08,
0x13,0x04,
0x13,0x02,
0x13,0x02,
0x16,0x04,
0x16,0x04,
0x16,0x18,
0x16,0x0a,
0x21,0x04,
0x13,0x04,
0x13,0x04,
0x03,0x08,
0x00,0x00
};
uint16 Fre; //存放獲取頻率值的變量
/*-----------------------------------------------
函數(shù)名:Timer_Init()
函數(shù)功能:對兩個定時器初始化
入口參數(shù):無
------------------------------------------------*/
void Timer_Init()
{
TMOD=0x11;
EA=1;
ET0=1;
ET1=0;
TR0=0;
TR1=0;
}
/*-----------------------------------------------
函數(shù)名:Timer0_Ser()
函數(shù)功能:定時器0的中斷服務(wù)程序,主要是產(chǎn)生需要的頻率
從而驅(qū)動喇叭發(fā)出相應(yīng)的音符
入口參數(shù):無
------------------------------------------------*/
void Timer0_i() interrupt 1
{
TH0=Fre/256;
TL0=Fre%256;
if(Music==0)
Music=1;
else Music=0;
}
/*-----------------------------------------------
函數(shù)名:Music_Play(uchar *MusicTab)
函數(shù)功能:音樂播放函數(shù),
入口參數(shù):*MusicTab 所要播放音樂的首地址
------------------------------------------------*/
void Music_Play(uint8 *MusicTab)
{
uint8 *pMusic;
uint8 temp,i;
pMusic=MusicTab; //將歌曲首地址給指針變量
while(*pMusic!=0)
{
if((*pMusic&0xf0)==0x00)
Fre=65536-1000000/FreTab_Low[*pMusic&0x0f];
else if((*pMusic&0xf0)==0x10)
Fre=65536-1000000/FreTab_Mid[*pMusic&0x0f];
else if((*pMusic&0xf0)==0x20)
Fre=65536-1000000/FreTab_Hight[*pMusic&0x0f];
TH0=Fre/256; //計算頻率初值,賦高八位
TL0=Fre%256; //計算頻率初值,賦低八位
TH1=0x3c; //定時器1賦初值,定時50ms
TL1=0xb0;
pMusic++; //獲得節(jié)拍值
temp=*pMusic;
TR0=1; //開啟定時器T0
TR1=1; //開啟定時器T1
for(i=0;i<temp;i++)
{
while(TF1==0); //判斷定時器1是否溢出
TH1=0x3c;
TL1=0xb0;
TF1=0;
}
pMusic++;
}
}
/*-----------------------------------------------
函數(shù)名:main()
函數(shù)功能:主函數(shù)
入口參數(shù):無
------------------------------------------------*/
void main()
{
while(1)
{
int k;
Timer_Init();
if(sw==0)
{
DelayMS(10);
if(sw==1)
break;
while(sw==0);
{
k++;
if(k==1)
{
Music_Play(Happy_Birthday1);
}
else if(k==2)
{
Music_Play(Happy_Birthday2);
}
else if(k==3)
{
Music_Play(Happy_Birthday3);
k=0;
}
}
}
}
}
懂了這個再同12864整合一下就OK了,不是很難
|