单片机音乐播放器制作

来源:互联网 发布:java微信商城源码下载 编辑:程序博客网 时间:2024/04/30 22:32
 

相关知识

要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计出这个半周期的时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可以在I/O脚上得到此频率的脉冲。

计数脉冲值与频率的关系公式如下:

N=Fi÷2÷Fr  

N:计数值

Fi:内部计数时一次为1us,故其频率为1MHz

Fr: 要产生的频率

其计数值的求法如下:

T=65536-N = 65536- Fi÷2÷Fr

例如:已知中音DO523Hz),求其计数值

T = 65536 500000 / 523 = 64580

2、按图连接:

2、常用节拍对照表:

 

 

/************************************************************************

*****music.c

*****created by zhangyongchang

*****date 2006 4.5

/**********************************************************************/

#include <reg51.h>

unsigned char m;   //m为频率常数

unsigned char n=0; //n为节拍常数

unsigned char i=0;

sbit bell=P1^7;

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 time0(void)  interrupt 1 using 1  //产生10MS精确定时

{  TH0=(65536-10000)/256;

   TL0=(65536-10000)%256;

   n--;

}

void delayms(unsigned char a)  //微秒延时程序

{

  while(--a);                  

}

void delay(void)   //延迟程序

{

int i,j;

for(i=50;i--;i>0)

  for(j=10000;j--;j>0) ;

}

void main()

{

    TMOD=(TMOD&0xf0)|0x01;

     TH0=(65536-10000)/256;

     TL0=(65536-10000)%256;

     EA=1;

     ET0=1;

     TR0=0;  

     while(1)

     {

     switch(music_tab[i])

     {

        case 0x00:

            i=0;delay(); break; // 曲终停顿一定时间

        case 0xff:

            i=i+1;delayms(100);break;  //遇到休止符停顿一定时间100微秒,再取下一个频率

        default:

m=music_tab[i++];n=music_tab[i++];//取频率到m,取节拍到n

                 TR0=1;

                 while(n!=0)

                  {

                  bell=!bell;

                  delayms(5*m);//调整产生的频率,可以通过在m前的值来修正音调的高低

                   }

    TR0=0;

      }

     }

}