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;

   }

 }

 

转载于:https://www.cnblogs.com/robotes/p/7795860.html

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值