【制作】基于金沙滩51单片机的蜂鸣器音乐

基于金沙滩51单片机的蜂鸣器音乐 - 克罗地亚狂想曲

当年刚学单片机蜂鸣器不久做的一个小项目,能用蜂鸣器播放音乐,之前的网站挂了,在这里重新发一下。

下面是原文:

当温度超过设置值时,怎么设置使蜂鸣器发出某首音乐声?

敲黑板画重点啦!!!这里的重点是音乐声而不是温度超过设置值

于是去参考了下宋老师的代码:

蜂鸣器音乐实例代码

#include <reg52.h>

sbit BUZZ = P1^6;  //蜂鸣器控制引脚

unsigned int code NoteFrequ[] = {  //中音1-7和高音1-7对应频率列表
    523,  587,  659,  698,  784,  880,  988,  //中音1-7
    1047, 1175, 1319, 1397, 1568, 1760, 1976  //高音1-7
};
unsigned int code NoteReload[] = { //中音1-7和高音1-7对应的定时器重载值
    65536 - (11059200/12) / (523*2),  //中音1
    65536 - (11059200/12) / (587*2),  //2
    65536 - (11059200/12) / (659*2),  //3
    65536 - (11059200/12) / (698*2),  //4
    65536 - (11059200/12) / (784*2),  //5
    65536 - (11059200/12) / (880*2),  //6
    65536 - (11059200/12) / (988*2),  //7
    65536 - (11059200/12) / (1047*2), //高音1
    65536 - (11059200/12) / (1175*2), //2
    65536 - (11059200/12) / (1319*2), //3
    65536 - (11059200/12) / (1397*2), //4
    65536 - (11059200/12) / (1568*2), //5
    65536 - (11059200/12) / (1760*2), //6
    65536 - (11059200/12) / (1976*2), //7
};
bit enable = 1;   //蜂鸣器发声使能标志
bit tmrflag = 0;  //定时器中断完成标志
unsigned char T0RH = 0xFF;  //T0重载值的高字节
unsigned char T0RL = 0x00;  //T0重载值的低字节

void PlayTwoTiger();

void main()
{
    unsigned int i;
    
    EA = 1;       //使能全局中断
    TMOD = 0x01;  //配置T0工作在模式1
    TH0 = T0RH;
    TL0 = T0RL;
    ET0 = 1;      //使能T0中断
    TR0 = 1;      //启动T0
    
    while (1)
    {
        PlayTwoTiger();  //播放乐曲--两支老虎
        for (i=0; i<40000; i++);  //停止一段时间
    }
}
/* 两只老虎乐曲播放函数 */
void PlayTwoTiger()
{
    unsigned char beat;   //当前节拍索引
    unsigned char note;   //当前节拍对应的音符
    unsigned int time = 0;      //当前节拍计时
    unsigned int beatTime = 0;  //当前节拍总时间
    unsigned int soundTime = 0; //当前节拍需发声时间
    //两只老虎音符表
    unsigned char code TwoTigerNote[] = {
        1,   2,   3, 1,    1,   2,   3, 1,   3, 4, 5,   3, 4, 5,
        5,6, 5,4, 3, 1,    5,6, 5,4, 3, 1,   1, 5, 1,   1, 5, 1,
    };
    //两只老虎节拍表,4表示一拍,1就是1/4拍,8就是2拍
    unsigned char code TwoTigerBeat[] = {
        4,   4,   4, 4,    4,   4,   4, 4,   4, 4, 8,   4, 4, 8,
        3,1, 3,1, 4, 4,    3,1, 3,1, 4, 4,   4, 4, 8,   4, 4, 8,
    };
    
    for (beat=0; beat<sizeof(TwoTigerNote); )  //用节拍索引作为循环变量
    {
        while (!tmrflag);  //每次定时器中断完成后,检测并处理节拍
        tmrflag = 0;
        if (time == 0)  //当前节拍播完则启动一个新节拍
        {
            note = TwoTigerNote[beat] - 1;
            T0RH = NoteReload[note] >> 8;
            T0RL = NoteReload[note];
            //计算节拍总时间,右移2位相当于除4,移位代替除法可以加快执行速度
            beatTime = (TwoTigerBeat[beat] * NoteFrequ[note]) >> 2;
            //计算发声时间,为总时间的0.75,移位原理同上
            soundTime = beatTime - (beatTime >> 2);
            enable = 1;  //指示蜂鸣器开始发声
            time++;
        }
        else  //当前节拍未播完则处理当前节拍
        {
            if (time >= beatTime)  //当前持续时间到达节拍总时间时归零,
            {                      //并递增节拍索引,以准备启动新节拍
                time = 0;
                beat++;
            }
            else  //当前持续时间未达到总时间时,
            {
                time++;   //累加时间计数
                if (time == soundTime)  //到达发声时间后,指示关闭蜂鸣器,
                {                       //插入0.25*总时间的静音间隔,
                    enable = 0;         //用以区分连续的两个节拍
                }
            }
        }
    }
}
/* T0中断服务函数,用于控制蜂鸣器发声 */
void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;   //重新加载重载值
    TL0 = T0RL;
    tmrflag = 1;
    if (enable)   //使能时反转蜂鸣器控制电平
        BUZZ = ~BUZZ;
    else          //未使能时关闭蜂鸣器
        BUZZ = 1;
}

下载到单片机后,传来了美妙的“两只老虎” ✧٩(ˊωˋ*)و✧

然而我并不喜欢把两只老虎作为报警音乐.......

宋老师的代码主要由数据和控制组成,而数据分为节拍数据和音调数据,那我们要换一首歌不就是换音调和节拍。

于是去百度“单片机蜂鸣器音乐代码”,得到如下结果:

都是些八月桂花,生日快乐,两只蝴蝶,祝你平安这些经典音乐,没有POP吗?

那就自己动手吧,只要得到节拍数据和音调数据就好了,应该有转换工具的,就像LED点阵一样有点阵图形转换工具,于是百度:

还真有 (*≧▽≦) , 叫 music encode

于是下载,解包

还有Dome和说明,太好了。于是下载了Dome。是八月桂花....

然而我不喜欢这个,翻了翻音乐列表,就设置为“克罗地亚狂想曲”吧

٩(●´৺`●)૭٩(●´৺'●)و

于是去问度娘要乐谱,好不容易找到了由玉面小嫣然改编的古筝简谱,其他的都是五线谱,原谅我看不懂五线谱 ( •̩̩̩̩_•̩̩̩̩ )


克罗地亚狂想曲钢琴谱

找到乐谱后就开始输乐谱........ (つд⊂) , 一个漫长的过程.........

终于输好了,生成代码下载进去...... ٩(●´৺`●)૭٩(●´৺'●)و

克罗地亚狂想曲乐谱

乐谱

 0, 0, 0, 0,| 7__, .1__, 6_, 0, 3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_,  0, .3__, 6__, 3__, 4__, 2_, 0, 6__, 2__,|
 #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__, 6.,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,|
 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,| 7__, .1__, 6_,  0, .3__, 6__,  3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__, 6.,| 7__, .1__, 6_,  0, .3__, 6__,  3__, 4__, 2_, 0,|
 #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__, 6.,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,|
 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,||| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__,  7__, 3__, 5__, 7__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,|
 .3__, 3__, #, 5__, 3__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__, 6,||| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__,  7__, 3__, 5__, 7__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,|
 .3__, 3__, #, 5__, 3__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__, 6,|| .3__, 6__, .1__, .2__,  .3__, 6__, .1__, .5__,  .4__, 6__, .3__, 6__, .2__, 6__, .1__, 6__,| .2__, 5__, 7__, .1__,  .2__, 5__, 7__, .4__,  .3__, 5__, .2__, 5__,  .1__, 5__, 7__, 5__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,|
 7_, 3_,  .1_, 7_,  6_, .3_,  .6,| 7_, 3_,  .1_, 7_,  6._, 6_,  6,| .3__, 6__, .1__, .2__,  .3__, 6__, .1__, .5__,  .4__, 6__, .3__, 6__,  .4__, 6__, .6__, 6__,| .5__, 7__, .2__, .6__,  .5__, 7__, .4__, 7__,  .3__, 3__, .2__, 3__,  .1__, 3__, 7__, 3__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,|
 7__, 3__, #, 5__, 7__,  .2__, 5__, 7__, .2__,  .3__, 7__, .2__, .3__,  #, .5__, .2__, .3__, .5__,| 7__, 3__, #, 5__, 7__,  .2__, 5__, 7__, .2__,  .3__, 7__, .2__, .3__,  #, .5__, .2__, .3__, .5__,| .6,  -,  -,  -,| 6.__, 1_, 3__,  2__, 6.__, 1__, 5.__,  6.__, 1_, 3__,  2__, 6.__, 1_,|
 0, 6__, 1__, 3__,  6.__, 1__, 6._,  0, #, 2.__, 3.__, 6.__,  1__, 2__, 1_,| 3.__, 5._, 3.__,  6.__,  3.__, 5.__, 2.__,  3.__, 5._, 3.__,  6.__, 3.__, 5._,| 7__, .1__, 6_,  0, .3__, 6__,  3__, 4__, 2_,  0,| #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,|
 7__, .1__, 6_,  0, .3__, 6__,  3__, 4__, 2_,  0,| #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  0, .3__, 6__,  7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,|
 7__, .1__, 6_,  0, .3__, 6__,  7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__, 6,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__,  7__, 3__, 5__, 7__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,|
 .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| .3__, 3__, #, 5__, 3__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,  6,| .3__, 6__, .1__, .2__,  .3__, 6__, .1__, .5__,  .4__, 6__, .3__, 6__,  .4__, 6__, .6__, 6__,| .5__, 7__, .2__, .6__,  .5__, 7__, .4__, 7__,  .3__, 3__, .2__, 3__,  .1__, 3__, 7__, 3__,|
 .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 7__,  .2__, 5__, 7__, .2__,  .3__, 7__, .2__, .3__,  #, .5__, .3__, .2__, .1__,| 7, -, .3, -,| 7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,|
 #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,| #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  0, .3__, 6__,  7__, .1__, 6_,  0, .3__, 6__,|
 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__,  6,| 7__, .1__, 6_,  0, .3__, 6__,  7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__,  6,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,|
 7__, 3__, #, 5__, 6__,  7__, 3__, 5__, 7__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| .3__, 3__, #, 5__, 3__,  .1__, 3__, 7__, 3__,  6__, 3__, .3__, 3__,  6,| .3__, 6__, .1__, .2__,  .3__, 6__, .1__, .5__,  .4__, 6__, .3__, 6__,  .4__, 6__, .6__, 6__,|
 .5__, 7__, .2__, .6__,  .5__, 7__, .4__, 7__,  .3__, 3__, .2__, 3__,  .1__, 3__, 7__, 3__,| .1__, 3__, 6__, 7__,  .1__, 3__, 6__, .1__,  .2__, 3__, .1__, 3__,  7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 7__,  .2__, 5__, 7__, .2__,  .3__, 7__, .2__, .3__,  #, .5__, .3__, .2__, .1__,|  7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,|
 #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,| #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,|
 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__,  6,| 7__, .1__, 6_,  0, .3__, 6__, 7__, .1__, 6_,  0, .3__, 6__,| 7__, .1__, 6_,  6_, #, 5__, 6__,  0, 7__, .1__,  6,| 7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,|
 #, 4__, #, 5__, 3_,  3_, 7.__, 1__,  6._, 7.__, 1__,  6.,| 7__, .1__, 6_,  7__, .1__, 6_,  3__, 4__, 2_,  3__, 4__, 2_,| #, 4__, #, 5__, 3_,  3_, 7_,  6_, .3_,  .6,| #, 4__, #, 5__, 3_,  3_, 7_,  3_, 6_,  .3,| #, 4__, #, 5__, 3_,  3_, 7_,  3_, 6_,  6,|

此处应有视频......

Nice!

需要用到的原理图和软件

DS18B20读写时序

Music Encode:点击下载

源代码和解释:

只播放音乐的代码:(按K1可以暂停哦......)

#include <reg52.h>
 
sbit keyin = P2^4;
sbit keyout = P2^3;
 
/*----------------音乐函数申明------------------------------*/
void Play();
void InitialSound(unsigned char *Sound0,unsigned char Signature0,
    unsigned char Octachord0,unsigned int Speed0);
/*----------------音乐数据申明------------------------------*/
extern unsigned char code Music_Croatian_Rhapsody[];
//数据太大,放后面了,所以加extern以说明
void delay10ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}
void main()
{
    unsigned int cnt = 0;
    InitialSound(Music_Croatian_Rhapsody,0,2,360);  //蜂鸣器初始化
     
    keyout = 0;
     
    while(1)
    {
        if(keyin == 0)
        {
            delay10ms();
            if(keyin == 0)
            {
                if(cnt<40)cnt = 200;
                else cnt = 20;
                while(keyin == 0);
            }
        }
         
        if(cnt < 40)
        {
            Play();                                 //蜂鸣器
        }
    }
}
 
 
 
/*-----------------------以下是蜂鸣器演奏------------------*/
#define SYSTEM_OSC      11059200    //12000000  //定义晶振频率12000000HZ
#define SOUND_SPACE     4/5         //定义普通音符演奏的长度分率,//每4分音符间隔
sbit    BeepIO    =     P1^6;       //定义输出管脚
 
unsigned int  code FreTab[12]  = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };                                  //1~7在频率表中的位置
unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };                      
unsigned char Sound_Temp_TH0,Sound_Temp_TL0;    //音符定时器初值暂存 
unsigned char Sound_Temp_TH1,Sound_Temp_TL1;    //音长定时器初值暂存
unsigned char Signature;
unsigned char Octachord;
unsigned int Speed;
unsigned char *Sound;
unsigned int NewFreTab[12];                     //新的频率表
unsigned char i,j;
unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
 
void InitialSound(unsigned char *Sound0,unsigned char Signature0,unsigned char Octachord0,unsigned int Speed0)
{
        Signature = Signature0;
    Octachord = Octachord0;
    Speed = Speed0;
    Sound = Sound0;
    
    for(i=0;i<12;i++)               // 根据调号及升降八度来生成新的频率表 
    {
        j = i + Signature;
        if(j > 11)
        {
            j = j-12;
            NewFreTab[i] = FreTab[j]*2;
        }
        else
            NewFreTab[i] = FreTab[j];

        if(Octachord == 1)
            NewFreTab[i]>>=2;
        else if(Octachord == 3)
            NewFreTab[i]<<=2;
    }                                   
    
    SoundLength = 1;
    while(Sound[SoundLength] != 0x00)   //计算歌曲长度
    {
        SoundLength+=2;
    }

    Point = 0;
    Tone   = Sound[Point];  
    Length = Sound[Point+1];            // 读出第一个音符和它时时值
    
    LDiv0 = 12000/Speed;                // 算出1分音符的长度(几个10ms)    
    LDiv4 = LDiv0/4;                    // 算出4分音符的长度 
    LDiv4 = LDiv4-LDiv4*SOUND_SPACE;    // 普通音最长间隔标准 
    
    BeepIO = 1;
    Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;   // 计算TL1应装入的初值  (10ms的初装值)
    Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;   // 计算TH1应装入的初值 
    TH1 = Sound_Temp_TH1;
    TL1 = Sound_Temp_TL1;
    TMOD  |= 0x11;
    ET0    = 1;
    ET1    = 0;
    TR0    = 0;
    TR1    = 0;
    EA     = 1;
}
 
void BeepTimer0(void) interrupt 1   //音符发生中断
{
    BeepIO = !BeepIO;
    TH0    = Sound_Temp_TH0;
    TL0    = Sound_Temp_TL0;
}
 
void Play()
{
    EA = 1;
    TR0   = 0;
    TR1   = 1;
    if(Point < SoundLength)
    {
        SL=Tone%10;                                 //计算出音符 
        SM=Tone/10%10;                              //计算出高低音 
        SH=Tone/100;                                //计算出是否升半 
        CurrentFre = NewFreTab[SignTab[SL-1]+SH];   //查出对应音符的频率     
        if(SL!=0)
        {
            if (SM==1) CurrentFre >>= 2;        //低音 
            if (SM==3) CurrentFre <<= 2;        //高音
            Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
            Sound_Temp_TH0 = Temp_T/256; 
            Sound_Temp_TL0 = Temp_T%256; 
            TH0 = Sound_Temp_TH0;  
            TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿 
        }
        SLen=LengthTab[Length%10];  //算出是几分音符
        XG=Length/10%10;            //算出音符类型(0普通1连音2顿音) 
        FD=Length/100;
        LDiv=LDiv0/SLen;            //算出连音音符演奏的长度(多少个10ms)
        if (FD==1) 
        {
            LDiv=LDiv+LDiv/2;
        }
        
        if(XG!=1)
        {           
            if(XG==0)               //算出普通音符的演奏长度 
            {
                if (SLen<=4)    
                {
                    LDiv1=LDiv-LDiv4;
                }else{
                    LDiv1=LDiv*SOUND_SPACE;
                }
            }else{
                LDiv1=LDiv/2;       //算出顿音的演奏长度 
            }
        }else{
            LDiv1=LDiv;
        }
        
        if(SL==0) 
        {
            LDiv1=0;
        }
        
        LDiv2=LDiv-LDiv1;       //算出不发音的长度 
        
        if (SL!=0)
        {
            TR0=1;
            for(i=LDiv1;i>0;i--)    //发规定长度的音 
            {
                while(TF1==0);      //等待节拍过去
                TH1 = Sound_Temp_TH1;//重装初值
                TL1 = Sound_Temp_TL1;
                TF1=0;              //清除中断标志位
            }
        }
        
        if(LDiv2!=0)
        {
            TR0=0; BeepIO=1;
            for(i=LDiv2;i>0;i--)    //音符间的间隔
            {
                while(TF1==0);      //等待节拍过去
                TH1 = Sound_Temp_TH1;//重装初值
                TL1 = Sound_Temp_TL1;
                TF1=0;              //清除中断标志位
            }
        }
        
        Point+=2; 
        Tone=Sound[Point];
        Length=Sound[Point+1];
        
    }
    else
    {
        /*SoundLength = len;
        Point = poi;*/
        InitialSound(Music_Croatian_Rhapsody,0,2,360);
    }
    BeepIO = 1;
    
    TR0   = 0;
    TR1   = 0;
}
 
//这里放生成的音乐数据
unsigned char code Music_Croatian_Rhapsody[]={
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x17,0x04, 0x18,0x04,
    0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x17, 0x1A,0x04,
    0x16,0x68, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
    0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
    0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x17,0x04,
    0x18,0x04, 0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03,
    0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04,
    0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
    0x21,0x04, 0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x7B,
    0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04,
    0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
    0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04, 0x1A,0x18,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04, 0x17,0x04,
    0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04,
    0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04,
    0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
    0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04, 0x17,0x04,
    0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
    0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04,
    0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
    0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02,
    0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x21,0x04,
    0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04, 0x1A,0x04,
    0x21,0x04, 0x1A,0x04, 0x20,0x04, 0x1A,0x04, 0x1F,0x04,
    0x1A,0x04, 0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04,
    0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x22,0x04, 0x21,0x04,
    0x19,0x04, 0x20,0x04, 0x19,0x04, 0x1F,0x04, 0x19,0x04,
    0x1B,0x04, 0x19,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
    0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x03, 0x17,0x03,
    0x1F,0x03, 0x1B,0x03, 0x1A,0x03, 0x21,0x03, 0x24,0x02,
    0x1B,0x03, 0x17,0x03, 0x1F,0x03, 0x1B,0x03, 0x10,0x03,
    0x1A,0x03, 0x1A,0x02, 0x21,0x04, 0x1A,0x04, 0x1F,0x04,
    0x20,0x04, 0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x23,0x04,
    0x22,0x04, 0x1A,0x04, 0x21,0x04, 0x1A,0x04, 0x22,0x04,
    0x1A,0x04, 0x24,0x04, 0x1A,0x04, 0x23,0x04, 0x1B,0x04,
    0x20,0x04, 0x24,0x04, 0x23,0x04, 0x1B,0x04, 0x22,0x04,
    0x1B,0x04, 0x21,0x04, 0x17,0x04, 0x20,0x04, 0x17,0x04,
    0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1B,0x04, 0x20,0x04,
    0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x04, 0x1B,0x04,
    0x20,0x04, 0x21,0x68, 0x23,0x04, 0x20,0x04, 0x21,0x04,
    0x23,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1B,0x04,
    0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x04,
    0x1B,0x04, 0x20,0x04, 0x21,0x68, 0x23,0x04, 0x20,0x04,
    0x21,0x04, 0x23,0x04, 0x24,0x00, 0x10,0x04, 0x15,0x03,
    0x17,0x04, 0x16,0x04, 0x10,0x04, 0x15,0x04, 0x0F,0x04,
    0x10,0x04, 0x15,0x03, 0x17,0x04, 0x16,0x04, 0x10,0x04,
    0x15,0x17, 0x1A,0x04, 0x15,0x04, 0x17,0x04, 0x10,0x04,
    0x15,0x04, 0x10,0x7B, 0x0C,0x04, 0x0D,0x04, 0x10,0x04,
    0x15,0x04, 0x16,0x04, 0x15,0x03, 0x0D,0x04, 0x0F,0x03,
    0x0D,0x04, 0x10,0x04, 0x0D,0x04, 0x0F,0x04, 0x0C,0x04,
    0x0D,0x04, 0x0F,0x03, 0x0D,0x04, 0x10,0x04, 0x0D,0x04,
    0x0F,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x7B, 0x18,0x68,
    0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x17,0x04,
    0x18,0x04, 0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03,
    0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04,
    0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
    0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
    0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
    0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
    0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
    0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04,
    0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04,
    0x1B,0x04, 0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x21,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
    0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68,
    0x19,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04,
    0x1A,0x02, 0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
    0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04,
    0x1A,0x04, 0x21,0x04, 0x1A,0x04, 0x22,0x04, 0x1A,0x04,
    0x24,0x04, 0x1A,0x04, 0x23,0x04, 0x1B,0x04, 0x20,0x04,
    0x24,0x04, 0x23,0x04, 0x1B,0x04, 0x22,0x04, 0x1B,0x04,
    0x21,0x04, 0x17,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x68, 0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x19,0x04,
    0x1B,0x04, 0x20,0x04, 0x21,0x04, 0x1B,0x04, 0x20,0x04,
    0x21,0x68, 0x23,0x04, 0x21,0x04, 0x20,0x04, 0x1F,0x04,
    0x1B,0x01, 0x21,0x01, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04,
    0x16,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68,
    0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
    0x17,0x04, 0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04,
    0x16,0x67, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
    0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
    0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04,
    0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
    0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02,
    0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x21,0x04,
    0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04, 0x1A,0x04,
    0x21,0x04, 0x1A,0x04, 0x22,0x04, 0x1A,0x04, 0x24,0x04,
    0x1A,0x04, 0x23,0x04, 0x1B,0x04, 0x20,0x04, 0x24,0x04,
    0x23,0x04, 0x1B,0x04, 0x22,0x04, 0x1B,0x04, 0x21,0x04,
    0x17,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
    0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68,
    0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x19,0x04, 0x1B,0x04,
    0x20,0x04, 0x21,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x68,
    0x23,0x04, 0x21,0x04, 0x20,0x04, 0x1F,0x04, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
    0x17,0x04, 0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04,
    0x16,0x67, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x03,
    0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68, 0x19,0x04,
    0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x03, 0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
    0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
    0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
    0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1B,0x04,
    0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x03,
    0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68, 0x19,0x04,
    0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04,
    0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x17,0x04,
    0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x67,
    0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03, 0x1B,0x03,
    0x1A,0x03, 0x21,0x03, 0x24,0x66, 0x18,0x68, 0x19,0x04,
    0x17,0x03, 0x17,0x03, 0x1B,0x03, 0x17,0x03, 0x1A,0x03,
    0x21,0x66, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x1B,0x03, 0x17,0x03, 0x1A,0x03, 0x1A,0x02, 0x00,0x00
};

题目的代码,emmm.....音乐数据太多,只放了一小段

#include <reg52.h>
#include <intrins.h>
//_nop_()函数所在头文件

char code waringset = 22;   //报警温度

/*----------------音乐函数申明------------------------------*/
void InitialSound(unsigned char *Sound0,unsigned char Signature0,
    unsigned char Octachord0,unsigned int Speed0);
void Play();


/*----------------音乐数据申明------------------------------*/
extern unsigned char code Music_Croatian_Rhapsody[];
//(数据太大,放后面了,所以加extern以说明)


/*----------------温度传感器申明----------------------------*/
bit Start18B20();           //初始化DS18B20
bit Get18B20Temp(int *temp);//读取温度


/*----------------LCD1602显示模块申明------------------------*/
void InitLcd1602();         //LCD1602初始化函数
void display();         //显示控制模块

/*-------------------LCD1602显示缓存-------------------------*/
unsigned char strbuff[11];//格式:“+125.0.0625°C”
unsigned char code waringstr[] = "     Alarm!     ";//报警显示文字
unsigned char code striswaring[] = "            ";//取消报警显示文字


/*----------------------其他全局变量-------------------------*/
int Temp = 0;       //读取到的当前温度值(16bit二进制)
int intT, decT;     //温度值的整数和小数部分
bit sign;           //温度值的正负(1正,0负)
bit iswaring = 0;   //是否报警标志位

void main()
{
    bit sta;                //是否成功读取标志
    unsigned int cnt = 0;   //检测标志,主要用于控制检测温度的频率
    
    InitialSound(Music_Croatian_Rhapsody,0,2,360);  //蜂鸣器初始化
    Start18B20();           //启动DS18B20
    InitLcd1602();          //初始化LCD1602液晶模块
    
    while(1)
    {
        cnt++;
        if(((iswaring == 0)&&(cnt>14000))||((iswaring == 1)&&(cnt>3)))              //大约0.8s(仿真得到) DS18B20最多750ms转化好
        {
            cnt = 0;
            sta = Get18B20Temp(&Temp);  //读取当前温度
            if (sta)                    //读取成功时,刷新当前温度显示
            {
                if((Temp >> 11) < 4)    //如果前面5位大部分是0
                {
                    sign = 1;           //正号,温度值为正
                }else{
                    sign = 0;           //温度值为负
                }
                
                if(sign == 1)           //正号
                {
                    intT = Temp >> 4;       //分离出温度值整数部分
                    decT = Temp & 0x0F;     //分离出温度值小数部分
                    decT = decT * 625;      //小数转换成10进制精度
                    //ftemp = intT + decT/10000;/*无效*/  //转换为浮点,以便比较
                }else{                  //负号
                    Temp = (~Temp)+1;       //取反后+1
                    intT = (Temp >> 4)*(-1);//分离出温度值整数部分
                    decT = Temp & 0x0F;     //分离出温度值小数部分
                    decT = decT * 625;      //小数转换成10进制精度           
                    //ftemp = (intT + decT/10000)*(-1);//转换为浮点
                }
            }
            else                            //读取失败时,给出错误信息
            {
                intT = 200;                 //这个值随便给,主要是大于126就好
                //ftemp = intT;
            }
            Start18B20();                   //重新启动下一次转换
            display();                      //显示
            
            if(intT >= waringset)
            {
                iswaring = 1;
            }else{
                iswaring = 0;
            }
            
        }
        
        if((iswaring == 1)&&(intT<126)&&(intT>-55))
        {
            Play();                                 //蜂鸣器
        }else{
            EA = 0;         //蜂鸣器是用中断,关掉
        }
    }
}

/*-----------------------以下是LCD1602显示驱动------------------*/
//定义LCD1602显示相关的IO接口
#define LCD1602_DB  P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E  = P1^5;
//LCD1602函数调用申明
void LcdShowStr(unsigned char x, unsigned char y,unsigned char *str, unsigned char len);
//显示控制模块
void display()
{
    
    static int intTb, decTb;    //温度值的整数和小数部分备份
    static bit signb;           //温度值的正负(1正,0负)备份
    if(iswaring == 1)
    {
        LcdShowStr(0,1,waringstr,16);
    }
    else
    {
        LcdShowStr(0,1,striswaring,11);
    }
    if((decTb != decT) || (intTb != intT) || (signb != sign))//如果有变化
    {
        /*备份当前值*/
        decTb = decT;
        intTb = intT;
        signb = sign;
        if(intT>126)    //如果信息错误,这个判断是温度显示特有的
        {
            unsigned char i = 1;
            //显示错误Error!
            strbuff[10] = '!';
            strbuff[9] = 'r';
            strbuff[8] = 'o';
            strbuff[7] = 'r';
            strbuff[6] = 'r';
            strbuff[5] = 'E';
            for(i = 0;i<5;i++)
            {
                strbuff[i] = ' ';
            }
        }else{          //信息正确
            if(sign == 1)strbuff[0] = ' ';else strbuff[0] = '-';//符号位
            if((intT/100) == 0)strbuff[1] = ' ';else strbuff[1] = ((intT/100)%10)+0x30;//百位
            if((intT/10) == 0)strbuff[2] = ' ';else strbuff[2] = ((intT/10)%10)+0x30;//十位
            if((intT) == 0)strbuff[3] = ' ';else strbuff[3] = (intT%10)+0x30;//个位加“.”
            if((decT/1000) == 0)strbuff[5] = '0';else strbuff[5] = ((decT/1000)%10)+0x30;//十分位
            if((decT/100) == 0)strbuff[6] = '0';else strbuff[6] = ((decT/100)%10)+0x30;//百分位
            if((decT/10) == 0)strbuff[7] = '0';else strbuff[7] = ((decT/10)%10)+0x30;//千分位
            if((decT) == 0)strbuff[8] = '0';else strbuff[8] = (decT%10)+0x30;//万分位
            /*以上是 载数码管缓存代码,把十进制分离,大家自己研究这里不多解释*/
            strbuff[4] = '.';
            strbuff[9] = 0XDF;//‘°’
            strbuff[10] = 'C';
        }
        
        LcdShowStr(4,0,strbuff,11); //显示,初始位置随意,只要能显示完整就好
    }
}

//等待液晶准备好
void LcdWaitReady()
{
    unsigned char sta;
     
    LCD1602_DB = 0xFF;
    LCD1602_RS = 0;
    LCD1602_RW = 1;
    do {
        LCD1602_E = 1;      //使能LCD1602
        sta = LCD1602_DB;   //读取状态字
        LCD1602_E = 0;      //避免干扰其他器件
    } while (sta & 0x80);   //第七位等于1表示液晶正忙,重复检测直到第七位等于0为止
}
//向LCD1602液晶写入一字节命令,cmd为待写入命令值
void LcdWriteCmd(unsigned char cmd)
{
    LcdWaitReady();
    LCD1602_RS = 0;
    LCD1602_RW = 0;
    LCD1602_DB = cmd;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
//向LCD1602液晶写入一字节数据,dat为待写入数据值
void LcdWriteDat(unsigned char dat)
{
    LcdWaitReady();
    LCD1602_RS = 1;
    LCD1602_RW = 0;
    LCD1602_DB = dat;
    LCD1602_E  = 1;
    LCD1602_E  = 0;
}
//设置显示RAM起始地址,亦即光标位置,(x,y)对应屏幕上的字符的坐标
void LcdSetCursor(unsigned char x, unsigned char y)
{
    unsigned char addr;
     
    if (y == 0)             //由输入的屏幕坐标计算显示RAM的地址
        addr = 0x00 + x;    //第一行字符地址从0x00起始
    else
        addr = 0x40 + x;    //第二行字符地址从0x40起始
    LcdWriteCmd(addr | 0x80);   //设置RAM地址
}
//在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,
//str-字符串指针,len-需显示的字符长度
void LcdShowStr(unsigned char x, unsigned char y,unsigned char *str, unsigned char len)
{
    LcdSetCursor(x, y);   //设置起始地址
    while (len--)         //连续写入len个字符数据
    {
        LcdWriteDat(*str++);  //先取str指向的数据,然后str自加1
    }
}

void InitLcd1602()//初始化1602液晶
{
    LcdWriteCmd(0x38);  //16*2显示,5*7点阵,8位数据接口
    LcdWriteCmd(0x0C);  //显示器开,光标关闭
    LcdWriteCmd(0x06);  //文字不动,地址自动+1
    LcdWriteCmd(0x01);  //清屏
}


/*-----------------------以下是温度传感器驱动------------------*/
//DS18B20通信引脚
sbit IO_18B20 = P3^2;
void DelayX10us(unsigned char t)
{
    do {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    } while (--t);
    /*_nop_()函数在12M晶振中延迟1us,为什么这里是8个_nop_()
    因为while和--t也是需要时间的,这里不一定是准确的10us/循环
    只是大致的时间*/
}
bit Get18B20Ack() //DS18B20存在检测函数 
{
    bit ack;

    EA = 0;             //关中断 
    IO_18B20 = 0;       //拉低引脚 
    DelayX10us(50);     //延时500us(480us - 960us) 
    IO_18B20 = 1;       //释放总线 
    DelayX10us(6);      //延时60us(15us - 60us) 
    ack = IO_18B20;     //读取响应(60us - 240us) 
    while(!IO_18B20);   //等待DS18B20释放总线 (60us - 240us) 
    EA = 1;             //取消关中断 

    return ack;         //返回是否存在 (0:存在 1:不存在) 
}

void  Write18B20(unsigned char dat) //写DS18B20 
{
    unsigned char mask;         //临时变量定义 
    EA = 0;                     //关中断 
    for(mask=0x01; mask!= 0; mask<<=1)  //循环发送单个bit位 
    {
        IO_18B20 = 0;           //拉低(请求读写操作) 
        _nop_();                //延时(1us < time <= 15us) 
        _nop_();
        if((mask&dat) == 0)     //按位读取dat 
            IO_18B20 = 0;       //本位是0,拉低 
        else
            IO_18B20 = 1;       //本位是1,拉高 
            //上面这个操作DS18B20读取(最小时间 0us<time<15us,
            //典型时间 15us,最大时间45us) 
        DelayX10us(6);          //等待60us(足够DS18B20读取) 
        IO_18B20 = 1;           //释放总线 
    }
    EA = 1;                     //取消关中断 
}

unsigned char Read18B20()       //读DS18B20 
{
    unsigned char dat;          //数据缓存变量 
    unsigned char mask;         //临时变量 

    EA = 0;                     //关中断 
    for(mask=0x01; mask!=0; mask<<=1)//同上循环按位操作 
    {
        IO_18B20 = 0;           //读写请求 
        _nop_();                //等待(1us < time < 15us) 
        _nop_();
        IO_18B20 = 1;           //初始化读操作 
        _nop_();                //等待DS18B20输出 
        _nop_();
        if(!IO_18B20)           //读 
            dat &= ~mask;       //“0” 
        else
            dat |= mask;        //“1” 
        DelayX10us(6);          //等待DS18B20释放总线 
    }
    EA = 1;                     //取消关中断 

    return dat;                 //返回数据 
}

bit Start18B20()        //初始化DS18B20 
{
    bit ack;            //存在标志 

    ack = Get18B20Ack();//检测存在 
    if(ack == 0)        //存在 
    {                   //写命令使工作
        Write18B20(0xCC);   //跳过ROM检测 
        Write18B20(0x44);   //启动温度转换 
    }
    return ~ack;        //返回是否成功(1是,0否) 
}

bit Get18B20Temp(int *temp) //获取DS18B20温度存于temp 
{
    bit ack;                //存在标志 
    unsigned char LSB, MSB; //数据低/高位 

    ack = Get18B20Ack();    //检测存在 
    if(ack == 0)            //存在 
    {                       //写指令 
        Write18B20(0xCC);   //跳过ROM检测 
        Write18B20(0xBE);   //读寄存器 
        LSB = Read18B20();  //读低位 
        MSB = Read18B20();  //读高位 
        *temp = ((int)MSB<<8) + LSB;    //合并 
    }
    return ~ack;            //返回结果(1成功,0失败) 
}


/*-----------------------以下是蜂鸣器演奏------------------*/
#define SYSTEM_OSC      11059200    //12000000  //定义晶振频率12000000HZ
#define SOUND_SPACE     4/5         //定义普通音符演奏的长度分率,//每4分音符间隔
sbit    BeepIO    =     P1^6;       //定义输出管脚

unsigned int  code FreTab[12]  = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };                                  //1~7在频率表中的位置
unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };                      
unsigned char Sound_Temp_TH0,Sound_Temp_TL0;    //音符定时器初值暂存 
unsigned char Sound_Temp_TH1,Sound_Temp_TL1;    //音长定时器初值暂存
unsigned char Signature;
unsigned char Octachord;
unsigned int Speed;
unsigned char *Sound;
unsigned int NewFreTab[12];                     //新的频率表
unsigned char i,j;
unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
//unsigned int len = 0,poi = 0;     //备份SoundLength


void InitialSound(unsigned char *Sound0,unsigned char Signature0,
    unsigned char Octachord0,unsigned int Speed0)
{
    Signature = Signature0;
    Octachord = Octachord0;
    Speed = Speed0;
    Sound = Sound0;
    
    for(i=0;i<12;i++)               // 根据调号及升降八度来生成新的频率表 
    {
        j = i + Signature;
        if(j > 11)
        {
            j = j-12;
            NewFreTab[i] = FreTab[j]*2;
        }
        else
            NewFreTab[i] = FreTab[j];

        if(Octachord == 1)
            NewFreTab[i]>>=2;
        else if(Octachord == 3)
            NewFreTab[i]<<=2;
    }                                   
    
    SoundLength = 1;
    while(Sound[SoundLength] != 0x00)   //计算歌曲长度
    {
        SoundLength+=2;
    }

    Point = 0;
    Tone   = Sound[Point];  
    Length = Sound[Point+1];            // 读出第一个音符和它时时值
    
    LDiv0 = 12000/Speed;                // 算出1分音符的长度(几个10ms)    
    LDiv4 = LDiv0/4;                    // 算出4分音符的长度 
    LDiv4 = LDiv4-LDiv4*SOUND_SPACE;    // 普通音最长间隔标准 
    
    BeepIO = 1;
    Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256;   // 计算TL1应装入的初值  (10ms的初装值)
    Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256;   // 计算TH1应装入的初值 
    TH1 = Sound_Temp_TH1;
    TL1 = Sound_Temp_TL1;
    TMOD  |= 0x11;
    ET0    = 1;
    ET1    = 0;
    TR0    = 0;
    TR1    = 0;
    EA     = 1;
        
    /*len = SoundLength;
    poi = Point;*/
}

void BeepTimer0(void) interrupt 1   //音符发生中断
{
    BeepIO = !BeepIO;
    TH0    = Sound_Temp_TH0;
    TL0    = Sound_Temp_TL0;
}

void Play()
{
    EA = 1;
    TR0   = 0;
    TR1   = 1;
    if(Point < SoundLength)
    {
        SL=Tone%10;                                 //计算出音符 
        SM=Tone/10%10;                              //计算出高低音 
        SH=Tone/100;                                //计算出是否升半 
        CurrentFre = NewFreTab[SignTab[SL-1]+SH];   //查出对应音符的频率     
        if(SL!=0)
        {
            if (SM==1) CurrentFre >>= 2;        //低音 
            if (SM==3) CurrentFre <<= 2;        //高音
            Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
            Sound_Temp_TH0 = Temp_T/256; 
            Sound_Temp_TL0 = Temp_T%256; 
            TH0 = Sound_Temp_TH0;  
            TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿 
        }
        SLen=LengthTab[Length%10];  //算出是几分音符
        XG=Length/10%10;            //算出音符类型(0普通1连音2顿音) 
        FD=Length/100;
        LDiv=LDiv0/SLen;            //算出连音音符演奏的长度(多少个10ms)
        if (FD==1) 
        {
            LDiv=LDiv+LDiv/2;
        }
        
        if(XG!=1)
        {           
            if(XG==0)               //算出普通音符的演奏长度 
            {
                if (SLen<=4)    
                {
                    LDiv1=LDiv-LDiv4;
                }else{
                    LDiv1=LDiv*SOUND_SPACE;
                }
            }else{
                LDiv1=LDiv/2;       //算出顿音的演奏长度 
            }
        }else{
            LDiv1=LDiv;
        }
        
        if(SL==0) 
        {
            LDiv1=0;
        }
        
        LDiv2=LDiv-LDiv1;       //算出不发音的长度 
        
        if (SL!=0)
        {
            TR0=1;
            for(i=LDiv1;i>0;i--)    //发规定长度的音 
            {
                while(TF1==0);      //等待节拍过去
                TH1 = Sound_Temp_TH1;//重装初值
                TL1 = Sound_Temp_TL1;
                TF1=0;              //清除中断标志位
            }
        }
        
        if(LDiv2!=0)
        {
            TR0=0; BeepIO=1;
            for(i=LDiv2;i>0;i--)    //音符间的间隔
            {
                while(TF1==0);      //等待节拍过去
                TH1 = Sound_Temp_TH1;//重装初值
                TL1 = Sound_Temp_TL1;
                TF1=0;              //清除中断标志位
            }
        }
        
        Point+=2; 
        Tone=Sound[Point];
        Length=Sound[Point+1];
        
    }
    else
    {
        /*SoundLength = len;
        Point = poi;*/
        InitialSound(Music_Croatian_Rhapsody,0,2,360);
    }
    BeepIO = 1;
    
    TR0   = 0;
    TR1   = 0;
}

//这里放生成的音乐数据
unsigned char code Music_Croatian_Rhapsody[]={
    0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x17,0x04, 0x18,0x04,
    0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
    0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
    0x10,0x02, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
    0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
    0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04,
    0x1A,0x04, 0x1B,0x04, 0x17,0x04, 0x19,0x04, 0x1B,0x04,
    0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
    0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
    0x17,0x68, 0x19,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
    0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
    0x17,0x04, 0x1A,0x02, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
    0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
    0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
    0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68,
    0x19,0x04, 0x1A,0x04, 0x1B,0x04, 0x17,0x04, 0x19,0x04,
    0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
    0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
    0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x21,0x04, 0x17,0x68, 0x19,0x04, 0x17,0x04, 0x1F,0x04,
    0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
    0x21,0x04, 0x17,0x04, 0x1A,0x02, 0x00,0x00
};

怎么样

音乐是不是很动听呢? ٩(●´৺`●)૭٩(●´৺'●)و,想尝试创作更多的蜂鸣器音乐吗?快发表你的看法吧!!

哔哩哔哩效果视频演示:https://www.bilibili.com/video/BV1Dt41197b9/

谢谢

原文地址:https://www.cnblogs.com/minuy/p/14261843.html