当前位置:   article > 正文

51单片机演奏音乐--源代码_51单片机歌曲代码

51单片机歌曲代码

搬一篇文章过来,2009年本人写在网易博客上的,现在网页博客已经关了,先挪过来,避免以后不在了。

关于程序的补充说明:

1、两个定时器的作用,及中断优先级的问题。
(1)定时器0——是一直输出方波,直到音乐结束;优先级最高;
(2)定时器1——控制输出方波的时间。当输出一个音符的时间到达规定长度时,改变定时器0的计数值,也就是改变方波频率,输出下一个音符;
2、系统的时钟频率
   注意下系统的时钟频率;

 

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

文件名:  MusicPlay.c
描  述:
         单片机演奏音乐;

程序结构描述:
main()函数在初始化后即进入while(1);功能主要在两个中断中完成;
定时器0中断主要输出一定频率的方波,初始值在于FreqTab中获取;
定时器1中断完成音长的控制,在完成特定音符的音长后读取下一个
音符,并且更新定时器0的初始设置值;

补充音乐知识:
音乐主要由音频和音长;
换个角度,
要输出一首音乐即用一个IO口输出特定时间长度和频率的方波

|<-------  音长1(节拍)  --------->| <----  音长2(节拍)------>| ...
      __     __     __      __      __       ___        ___       ___
|__|    |__|    |__|    |__|    |__|    |___|      |___|      |___|      |___

|       音符1(频率1)              |     音符2(频率2)   |  ...
Email:xiesx1985@126.com
by xiesx,2008.12.26
**************************************************************/

 

  1. #include <reg51.h>
  2. unsigned char volatile FlagBeat;   // 基本节拍单位计数变量
  3. unsigned int volatile FreqTemp;
  4. unsigned char volatile music_temp; //暂时存放从MusicTable数组中读出的变量
  5. unsigned char volatile beat;   //
  6. unsigned char volatile freq;   //简谱码对应T值数组的下标
  7. unsigned char volatile   *pmusic;
  8. sbit Pin_Buzzer=P1^0;
  9. unsigned int code FreqTab[]={ //简谱对应的简谱码、T值
  10.                               65535,
  11.          64260,64400,64524,64580,64684,
  12.          64777,64820,64898,64968,65030,
  13.          65058,65110,65157,65178,65217
  14.                             };
  15. unsigned char code MusicTable[]={//音符节拍码
  16.                                   0x82,0x01,0x81,0x94,0x84,
  17.           0xb4,0xa4,0x04,
  18.           0x82,0x01,0x81,0x94,0x84,
  19.           0xc4,0xb4,0x04,
  20.          
  21.           0x82,0x01,0x81,0xf4,0xd4,
  22.           0xb4,0xa4,0x94,
  23.           0xe2,0x01,0xe1,0xd4,0xb4,
  24.           0xc4,0xb4,0x04,
  25.         
  26.           0x82,0x01,0x81,0x94,0x84,
  27.           0xb4,0xa4,0x04,
  28.           0x82,0x01,0x81,0x94,0x84,
  29.           0xc4,0xb4,0x04,
  30.           0x82,0x01,0x81,0xf4,0xd4,
  31.           0xb4,0xa4,0x94,
  32.           0xe2,0x01,0xe1,0xd4,0xb4,
  33.           0xc4,0xb4,0x04,
  34.           0x00
  35.           };
  36. //中断优先级最高,产生FreqTab表中对应的频率
  37. void timer0() interrupt 1 using 0
  38. {
  39.  TR0=0;
  40.  TL0= FreqTemp;
  41.     TH0= FreqTemp>>8;
  42.  TR0=1;
  43.     Pin_Buzzer=~Pin_Buzzer;
  44. }
  45. //用于控制音长的定时中断, 每1/4拍变量FlagBeat加1
  46. //47ms中断一次
  47. void timer1() interrupt 3 using 1
  48. {
  49.  FlagBeat++;
  50.  TR1=0;
  51.  TL1=0x68;
  52.  TH1=0x48;
  53.  TR1=1;
  54.  //
  55.    if(*pmusic==0x00)pmusic=MusicTable;
  56.      {
  57.     if(FlagBeat==beat)
  58.     {
  59.      FlagBeat=0;
  60.     music_temp=*pmusic;
  61.      beat= music_temp&0x0F; //取得节拍数
  62.       beat=beat*4;
  63.      freq =music_temp>>4; //取得音符编码
  64.      pmusic++;
  65.    
  66.      if(freq==0)TR0=0;
  67.      else
  68.      {
  69.           TR0=0;
  70.     FreqTemp=FreqTab[freq];
  71.           TL0= FreqTemp;
  72.           TH0= FreqTemp>>8;
  73.           TR0=1;
  74.      }
  75.     }
  76.        }
  77.  
  78. }
  79. void main()
  80. {
  81.  
  82.     pmusic=MusicTable;
  83.  beat=1;
  84.     FlagBeat=0;
  85.  TMOD=0x11;//定时器0,1都工作16位计数方式 
  86.  ET0=1;   //允许定时器0溢出中断;
  87.  ET1=1;   //允许定时器1溢出中断
  88.  EA=1;
  89.  TL1=0xF0;
  90.     TH1=0xFF;
  91.     TR1=1;
  92.  while(1)
  93.  {
  94.  }
  95.  
  96. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/563809
推荐阅读
相关标签
  

闽ICP备14008679号