单片机控制蜂鸣器播放音乐程序遇到问题,求高手帮忙解...

2019-07-15 22:47发布

我想用单片机控制蜂鸣器播放一些音乐,用了一个八月桂花遍地开的程序,想把里面的歌曲改掉,用谱曲的软件改了之后,播放的就乱了,没有调子了。求高手解释下怎么改进啊!!原程序如下
/************************************************************************  
[文件名]  C51音乐程序(八月桂花)  
[功能]    通过单片机演奏音乐  

/**********************************************************************/   
#include <REG52.H>   
#include <INTRINS.H>   
//本例采用89C52, 晶振为11.0592MHZ   
//关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.   
//频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;   
//所以拿出谱子, 试探编吧!   

sbit Beep =  P3^7 ;

unsigned char n=0;  //n为节拍常数变量   
unsigned char code music_tab[] ={                                                                 //这里用取谱软件取出生日快乐的歌的代码后,播放时就乱码了。
0x18, 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 int0()  interrupt 1   //采用中断0 控制节拍   
{  TH0=0xd8;   
   TL0=0xef;   
   n--;   
}   

void delay (unsigned char m)   //控制频率延时   
{   
unsigned i=3*m;   
while(--i);   
}   

void delayms(unsigned char a)  //豪秒延时子程序   
{   
  while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!   
}   

void main()   
{ unsigned char p,m;   //m为频率常数变量   
  unsigned char i=0;   
  //TMOD&=0x0f;   
  TMOD|=0x01;   
  TH0=0xd8;
        TL0=0xef;   
  IE=0x82;     
   while(1)   
    {   
     p=music_tab;   
     if(p==0x00)      
     { i=0, delayms(1000);}     //如果碰到结束符,延时1秒,回到开始再来一遍   
     else if(p==0xff)
     { i=i+1;delayms(100),TR0=0;}  //若碰到休止符,延时100ms,继续取下一音符   
      else      
      {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数   
         TR0=1;                                             //开定时器1   
         while(n!=0) Beep=~Beep,delay(m);                         //等待节拍完成, 通过P1口输出音频(可多声道哦!)   
       TR0=0;                                             //关定时器1   
    }   
}  



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
10条回答
paddylee2011
2019-07-16 16:54
聂敏林 发表于 2013-8-27 15:38
是这个原因吗?那样怎么改进呢?求指教。。。我之前想的是音乐有不同的调子和节拍,但是不知道如何设置定 ...

//格式为: 频率常数, 节拍常数, 频率常数, 节拍常数, //求解释,望大家能帮帮忙。
这一句就是关键,以0x18的频率发音0x30的时间,再以0x1C的频率发音0x10的时间,再以0x20的频率发音0x40的时间,你明白规律了吗?

一周热门 更多>