⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 音乐演奏.lst

📁 用于单片机开发实验平台上
💻 LST
📖 第 1 页 / 共 2 页
字号:
C51 COMPILER V7.06   音乐演奏                                                              01/25/2007 01:19:39 PAGE 1   


C51 COMPILER V7.06, COMPILATION OF MODULE 音乐演奏
OBJECT MODULE PLACED IN 音乐演奏.OBJ
COMPILER INVOKED BY: D:\keil c51\C51\BIN\C51.EXE 音乐演奏.c BROWSE DEBUG OBJECTEXTEND

stmt level    source

   1          #ifndef __SOUNDPLAY_H_REVISION_FIRST__
   2          #define __SOUNDPLAY_H_REVISION_FIRST__
   3          
   4          #include <reg51.h>
   5          
   6          //**************************************************************************
   7          
   8          #define SYSTEM_OSC   11059200//12000000 //定义晶振频率12000000HZ
   9          #define SOUND_SPACE  4/5   //定义普通音符演奏的长度分率,//每4分音符间隔
  10          sbit    BeepIO    =    P2^6;  //定义输出管脚
  11          
  12          unsigned int  code FreTab[12]  = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表
  13          unsigned char code SignTab[7]  = { 0,2,4,5,7,9,11 };           //1~7在频率表中的位置
  14          unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };      
  15          unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存 
  16          unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存
  17          //**************************************************************************
  18          void InitialSound(void)
  19          {
  20   1       BeepIO = 1;
  21   1       Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值  (10ms的初装值)
  22   1       Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256; // 计算TH1应装入的初值 
  23   1       TH1 = Sound_Temp_TH1;
  24   1       TL1 = Sound_Temp_TL1;
  25   1       TMOD  |= 0x11;
  26   1       ET0    = 1;
  27   1       ET1    = 0;
  28   1       TR0    = 0;
  29   1       TR1    = 0;
  30   1       EA     = 1;
  31   1      }
  32          
  33          void BeepTimer0(void) interrupt 1 //音符发生中断
  34          {
  35   1       BeepIO = !BeepIO;
  36   1       TH0    = Sound_Temp_TH0;
  37   1        TL0    = Sound_Temp_TL0;
  38   1      }
  39          //**************************************************************************
  40          void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
  41          {
  42   1       unsigned int NewFreTab[12];  //新的频率表
  43   1       unsigned char i,j;
  44   1       unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
  45   1       unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
  46   1       for(i=0;i<12;i++)     // 根据调号及升降八度来生成新的频率表 
  47   1       {
  48   2        j = i + Signature;
  49   2        if(j > 11)
  50   2        {
  51   3         j = j-12;
  52   3         NewFreTab[i] = FreTab[j]*2;
  53   3        }
  54   2        else
  55   2         NewFreTab[i] = FreTab[j];
C51 COMPILER V7.06   音乐演奏                                                              01/25/2007 01:19:39 PAGE 2   

  56   2      
  57   2        if(Octachord == 1)
  58   2         NewFreTab[i]>>=2;
  59   2        else if(Octachord == 3)
  60   2         NewFreTab[i]<<=2;
  61   2       }         
  62   1       
  63   1       SoundLength = 0;
  64   1       while(Sound[SoundLength] != 0x00) //计算歌曲长度
  65   1       {
  66   2        SoundLength+=2;
  67   2       }
  68   1      
  69   1       Point = 0;
  70   1       Tone   = Sound[Point]; 
  71   1       Length = Sound[Point+1];    // 读出第一个音符和它时时值
  72   1       
  73   1       LDiv0 = 12000/Speed;    // 算出1分音符的长度(几个10ms)  
  74   1       LDiv4 = LDiv0/4;      // 算出4分音符的长度 
  75   1       LDiv4 = LDiv4-LDiv4*SOUND_SPACE;  // 普通音最长间隔标准 
  76   1       TR0   = 0;
  77   1       TR1   = 1;
  78   1       while(Point < SoundLength)
  79   1       {
  80   2        SL=Tone%10;         //计算出音符 
  81   2        SM=Tone/10%10;         //计算出高低音 
  82   2        SH=Tone/100;         //计算出是否升半 
  83   2        CurrentFre = NewFreTab[SignTab[SL-1]+SH];  //查出对应音符的频率  
  84   2        if(SL!=0)
  85   2        {
  86   3         if (SM==1) CurrentFre >>= 2;   //低音 
  87   3         if (SM==3) CurrentFre <<= 2;   //高音
  88   3         Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
  89   3         Sound_Temp_TH0 = Temp_T/256; 
  90   3         Sound_Temp_TL0 = Temp_T%256; 
  91   3         TH0 = Sound_Temp_TH0;  
  92   3         TL0 = Sound_Temp_TL0 + 12; //加12是对中断延时的补偿 
  93   3        }
  94   2        SLen=LengthTab[Length%10];  //算出是几分音符
  95   2        XG=Length/10%10;    //算出音符类型(0普通1连音2顿音) 
  96   2        FD=Length/100;
  97   2        LDiv=LDiv0/SLen;    //算出连音音符演奏的长度(多少个10ms)
  98   2        if (FD==1) 
  99   2         LDiv=LDiv+LDiv/2;
 100   2        if(XG!=1) 
 101   2         if(XG==0)     //算出普通音符的演奏长度 
 102   2          if (SLen<=4) 
 103   2           LDiv1=LDiv-LDiv4;
 104   2          else
 105   2           LDiv1=LDiv*SOUND_SPACE;
 106   2         else
 107   2          LDiv1=LDiv/2;   //算出顿音的演奏长度 
 108   2        else
 109   2         LDiv1=LDiv;
 110   2        if(SL==0) LDiv1=0;
 111   2         LDiv2=LDiv-LDiv1;   //算出不发音的长度 
 112   2          if (SL!=0)
 113   2        {
 114   3         TR0=1;
 115   3         for(i=LDiv1;i>0;i--)  //发规定长度的音 
 116   3         {
 117   4          while(TF1==0);
C51 COMPILER V7.06   音乐演奏                                                              01/25/2007 01:19:39 PAGE 3   

 118   4          TH1 = Sound_Temp_TH1;
 119   4          TL1 = Sound_Temp_TL1;
 120   4          TF1=0;
 121   4         }
 122   3        }
 123   2        if(LDiv2!=0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -