C51蜂鳴器演奏兩只老虎


/*兩只老虎**/

#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;

   }

 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM