lllll 发表于 2009-10-22 20:41:43

51单片机音乐C程序怎么解读????

#include <reg52.h>
unsigned char Count;
sbit _Speak =P2^3 ;                        //讯响器控制脚 

unsigned char code SONG[] ={      //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
                                  //路边的野华不要采
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,
0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,
0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,
0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,
0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,

};

void Time0_Init()
{
      TMOD = 0x01;
      IE          = 0x82;
      TH0= 0xD8;
      TL0= 0xEF;                //12MZ晶振,10ms
}

void Time0_Int() interrupt 1
{
      TH0 = 0xD8;
      TL0 = 0xEF;
      Count++;                        //长度加1
}

/*-------------------------------------------------
功能:1MS延时子程序
-------------------------------------------------*/
void Delay_xMs(unsigned int x)
{
    unsigned int i,j;
    for( i =0;i < x;i++ )
    {
      for( j =0;j<3;j++ );
    }
}

/*-------------------------------------------------
功能:歌曲播放子程序i为播放哪一段曲目
-------------------------------------------------*/
void Play_Song(unsigned char i)
{
      unsigned char Temp1,Temp2;
      unsigned int Addr;
      Count = 0;                                                //中断计数器清0
      Addr = i * 217;
      while(1)
      {
                Temp1 = SONG;
            if ( Temp1 == 0xFF )          //休止符
            {
                  TR0 = 0;
                  Delay_xMs(100);
            }
            else if ( Temp1 == 0x00 )          //歌曲结束符
            {
                        Addr++;
                         i++;
                        if(i==2)
                        {
                              i=0;
                            return;
                        }
            }
            else
            {
                  Temp2 = SONG;
                  TR0 = 1;
                        while(1)
                        {
                            _Speak = ~_Speak;
                            Delay_xMs(Temp1);
                            if ( Temp2 == Count )
                            {
                                    Count = 0;
                                    break;
                            }
                         }
            }
      }
}
/*-------------------------------------------------
功能:主程序
-------------------------------------------------*/
void main()
{
      Time0_Init();                        //定时器0中断初始化
      while(1)
      {
                Play_Song(0);
      }
}

程序看似简单,但是就是不明白,数组里的一个字节什么意思??
else
            {
                  Temp2 = SONG;
                  TR0 = 1;
                        while(1)
                        {
                            _Speak = ~_Speak;
                            Delay_xMs(Temp1);
                            if ( Temp2 == Count )
                            {
                                    Count = 0;
                                    break;
                            }
                         }
            }
      }
这里也不明白???

smallworm 发表于 2009-10-22 21:02:19

应该是代表时间长短吧

58180698 发表于 2009-10-22 21:16:24

请问一下楼主,你的这个程序确定没有问题吗?

lllll 发表于 2009-10-22 22:04:51

我从网上找的,看这个结构比较简单,我试过,没问题。。

cbs110 发表于 2010-7-3 11:08:05

这程序貌似有问题吧,定时器中断里TH0,TL0为固定值?

newlife0828 发表于 2010-12-7 21:28:56

#include <reg52.h>
unsigned char Count;
sbit _Speak =P3^7 ;                        //讯响器控制脚 
unsigned char code SONG[] ={      //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00,
//路边的野华不要采
0x30,0x1C,0x10,0x20,0x40,0x1C,0x10,0x18,0x10,0x20,0x10,0x1C,0x10,0x18,0x40,0x1C,
0x20,0x20,0x20,0x1C,0x20,0x18,0x20,0x20,0x80,0xFF,0x20,0x30,0x1C,0x10,0x18,0x20,
0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,
0x30,0x80,0xFF,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x20,0x1C,0x10,0x18,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,
0x20,0x2B,0x40,0x20,0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,
0x40,0x20,0x20,0x2B,0x20,0x26,0x20,0x20,0x20,0x30,0x80,0x20,0x30,0x1C,0x10,0x20,
0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,0x15,0x1F,
0x05,0x20,0x10,0x1C,0x10,0x20,0x20,0x26,0x20,0x2B,0x20,0x30,0x20,0x2B,0x40,0x20,
0x30,0x1C,0x10,0x18,0x20,0x15,0x20,0x1C,0x20,0x20,0x20,0x26,0x40,0x20,0x20,0x2B,
0x20,0x26,0x20,0x20,0x20,0x30,0x30,0x20,0x30,0x1C,0x10,0x18,0x40,0x1C,0x20,0x20,
0x20,0x26,0x40,0x13,0x60,0x18,0x20,0x15,0x40,0x13,0x40,0x18,0x80,0x00,

};
/*******************************************************************************
** 函数:Time0_Init()
** 描述:定时器0赋初值,晶振为12M,定时10ms
*******************************************************************************/
void Time0_Init()   
{
        TMOD = 0x01;   //定义为16位计数器
        IE   = 0x82;   //0x82 转化为二进制时为1000 0010 ,意思为开总中断,开定时器0中断.
        TH0= 0xD8;    //高四位赋初值   也可写为TH0=(65536-10000)/256
        TL0= 0xEF;    // 低四位赋初值也可写为TL0=(65536-10000)%256      
}
/*******************************************************************************
** 函数:Time0_Int() interrupt 1
** 描述:定时器0中断
*******************************************************************************/
void Time0_Int() interrupt 1   
{
        TH0=0xD8;   //重赋初值
        TL0=0xEF;    //重赋初值
        Count++;         //长度加1
}
/*******************************************************************************
** 函数:Delay_xMs(unsigned int x)
** 描述:50us
*******************************************************************************/
void Delay_xMs(unsigned int x)
{
        unsigned int i,j;
        for(i=0;i<x;i++)
        {
                for(j=0;j<3;j++);
        }
}
/*******************************************************************************
** 函数:Play_Song
** 描述:歌曲播放子程序i为播放哪一段曲目
*******************************************************************************/
void Play_Song(unsigned char i)
{
        unsigned char Temp1,Temp2;   //Temp1(频率)调用数组内的单数,Temp2(拍子)调用数组里的偶数,
        unsigned int Addr;
        Count=0;      //中断计数器清0   过10ms自加一次.
        Addr=i*217;   //如果i为0,计算从0开始,如果i为1,计算从217开始,也就是第二首歌的起始地址.
        while(1)
        {
                Temp1=SONG;      
                if(Temp1==0xFF)          //休止符
                {
                        TR0=0;   //关闭TO.
                        Delay_xMs(100);
                }
                else if (Temp1==0x00)          //歌曲结束符
                {
                        Addr++;
                        i++;
                        if(i==2)
                        {
                                i=0;
                                return;    //返回
                        }
                }
                else
                {
                        Temp2=SONG;
                        TR0=1;   //开定时器T0
                        while(1)
                        {
                                _Speak = ~_Speak;
                                Delay_xMs(Temp1);
                                if (Temp2== Count)
                                {
                                        Count = 0;
                                        break;    //跳出while(1)循环
                                }
                        }
                }
        }
}
/*******************************************************************************
** 函数:main()
** 描述:
*******************************************************************************/
void main()
{
        Time0_Init();                        //定时器0中断初始化
        while(1)
        {
                Play_Song(0);
        }
}






这是我对你的程序的一些注释,希望能对你有所帮助.
可能也有很多不足之处,希望大家多多指正.

wxhland 发表于 2010-12-8 00:36:55

else
{
Temp2=SONG;
TR0=1;   //开定时器T0
while(1)
{
_Speak = ~_Speak;
Delay_xMs(Temp1);
if (Temp2== Count)
{
Count = 0;
break;    //跳出while(1)循环
}
}
}
这一段注释的不是太清楚,麻烦楼上再解释下好吗?

wxhland 发表于 2010-12-8 00:41:59

有点理解了,temp1代表频率,temp2代表这种频率声音持续的时间。

southpolefirn 发表于 2010-12-8 00:44:07

注意这段音乐程序的实现是:频率(声音高低),节拍(是这个频率的持续时间)。

cqsgcqsg 发表于 2011-2-22 23:35:20

692446 发表于 2012-12-4 13:13:59

{:titter:}{:titter:}{:titter:}{:titter:}
页: [1]
查看完整版本: 51单片机音乐C程序怎么解读????