1. 程式人生 > >C51蜂鳴器演奏兩只老虎

C51蜂鳴器演奏兩只老虎

beat 函數 char 播放 綁定 else i++ 重新 ndt

/*兩只老虎**/

#include<reg52.h> sbit Buzz = P1^6; //聲明綁定蜂鳴器

unsigned int code NoteFrequ[]={ 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-7

  65536 - (11059200/12) /(587*2),

  65536 - (11059200/12) /(659*2),

  65536 - (11059200/12) /(698*2),

  65536 - (11059200/12) /(784*2),

  65536 - (11059200/12) /(880*2),

  65536 - (11059200/12) /(988*2),

  65536 - (11059200/12) /(1047*2),//高音1-7

  65536 - (11059200/12) /(1175*2),

  65536 - (11059200/12) /(1319*2),

  65536 - (11059200/12) /(1397*2),

  65536 - (11059200/12) /(1568*2),

  65536 - (11059200/12) /(1760*2),

  65536 - (11059200/12) /(1970*2)};

bit enable = 1; //發聲使能標誌

bit tmrflay = 0; //定時器 中斷完成標誌

unsigned char T0RH = 0xff; //T0重載值高字節

unsigned char T0RL = 0x00; //T0重載值低字節

void PlayTwoTiger(); void main(){

  unsigned int i;

   EA = 1;

   TMOD =0x01; //模式1

   TH0 = T0RH;

  TL0 = T0RL;

  ET0 = 1; //使能T0中斷

  TR0 = 1; //啟動

  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 PlayTwoTigerNote[]={ //音符表

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

};

unsigned char code PlayTwoBeat[]={ //節拍表,4表示一拍,1表示1/4拍,8表示兩拍

  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(PlayTwoTigerNote);){ //節拍索引循環變量

while(!tmrflay); //每次定時器中斷完成 節拍處理

tmrflay = 0;

if(time == 0){ //節拍播放完成重啟

   note = PlayTwoTigerNote[beat]-1;

  T0RH = NoteReload[note]>>8;

  T0RL = NoteReload[note]; //計算總時間,右移2位等於除4,移位代替除法加快速度

  beattime = (PlayTwoBeat[beat]*NoteFrequ[note])>>2; //計算發聲時間,為總時間的0.75s

   soundtime =beattime - (beattime>>2);

  enable = 1; //開始發聲

  time++;

   }else{ //節拍播放未結束則繼續處理

    if(time >= beattime){ //當前時間清零

      time = 0; //準備重新啟動

    beat++;

    }else{ //累加時間

   time++;

  if(time == soundtime){ //發聲時間到達,關閉蜂鳴器

    enable =0; //用以區分連續兩個節拍

     }

    }

  }

}

}

void InterRupt() interrupt 1{//中斷服務

TH0 =T0RH;

TL0 =T0RL;

tmrflay = 1;

if(enable){

  Buzz=~Buzz;

  }else{

    Buzz=1;

   }

}

C51蜂鳴器演奏兩只老虎