東南西北風

生活就像一杯加了糖的苦咖啡。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

51单片机播放音乐(转)

Posted on 2009-01-05 10:16  东南西北风  阅读(462)  评论(0)    收藏  举报

 

  1/*说明**************************************************************************
  2曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长., 0,0}; 末尾:0,0 表示结束(Important)
  3
  4音高由三位数字组成:   个位是表示 1~7 这七个音符    十位是表示音符所在的音区:1-低音,2-中音,3-高音;   百位表示这个音符是否要升半音: 0-不升,1-升半音。  音长最多由三位数字组成:    个位表示音符的时值,其对应关系是:     |数值(n):  |0 |1 |2 |3 | 4 | 5 | 6     |几分音符: |1 |2 |4 |8 |16 |32 |64   音符=2^n   十位表示音符的演奏效果(0-2):  0-普通,1-连音,2-顿音   百位是符点位: 0-无符点,1-有符点
  5调用演奏子程序的格式
  6   Play(乐曲名,调号,升降八度,演奏速度);
  7|乐曲名           : 要播放的乐曲指针,结尾以(0,0)结束;
  8|调号(0-11)       : 是指乐曲升多少个半音演奏;
  9|升降八度(1-3)   : 1:降八度, 2:不升不降, 3:升八度;
 10|演奏速度(1-12000): 值越大速度越快;
 11
 12***************************************************************************/

 13#ifndef __SOUNDPLAY_H_REVISION_FIRST__
 14#define __SOUNDPLAY_H_REVISION_FIRST__
 15
 16#include 
 17
 18//**************************************************************************
 19
 20#define SYSTEM_OSC   11059200//12000000 //定义晶振频率12000000HZ
 21#define SOUND_SPACE  4/5   //定义普通音符演奏的长度分率,//每4分音符间隔
 22sbit    BeepIO    =    P2^6;  //定义输出管脚
 23
 24unsigned int  code FreTab[12]  = 262,277,294,311,330,349,369,392,415,440,466,494 }//原始频率表
 25unsigned char code SignTab[7]  = 0,2,4,5,7,9,11 };           //1~7在频率表中的位置
 26unsigned char code LengthTab[7]= 1,2,4,8,16,32,64 };      
 27unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存 
 28unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存
 29//**************************************************************************
 30void InitialSound(void)
 31{
 32BeepIO = 1;
 33Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256// 计算TL1应装入的初值  (10ms的初装值)
 34Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256// 计算TH1应装入的初值 
 35TH1 = Sound_Temp_TH1;
 36TL1 = Sound_Temp_TL1;
 37TMOD  |= 0x11;
 38ET0    = 1;
 39ET1    = 0;
 40TR0    = 0;
 41TR1    = 0;
 42EA     = 1;
 43}

 44
 45void BeepTimer0(void) interrupt 1 //音符发生中断
 46{
 47BeepIO = !BeepIO;
 48TH0    = Sound_Temp_TH0;
 49  TL0    = Sound_Temp_TL0;
 50}

 51//**************************************************************************
 52void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
 53{
 54unsigned int NewFreTab[12];  //新的频率表
 55unsigned char i,j;
 56unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
 57unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
 58for(i=0;i<12;i++)     // 根据调号及升降八度来生成新的频率表 
 59{
 60  j = i + Signature;
 61  if(j > 11)
 62  {
 63   j = j-12;
 64   NewFreTab[i] = FreTab[j]*2;
 65  }

 66  else
 67   NewFreTab[i] = FreTab[j];
 68
 69  if(Octachord == 1)
 70   NewFreTab[i]>>=2;
 71  else if(Octachord == 3)
 72   NewFreTab[i]<<=2;
 73}
         
 74
 75SoundLength = 0;
 76while(Sound[SoundLength] != 0x00//计算歌曲长度
 77{
 78  SoundLength+=2;
 79}

 80
 81Point = 0;
 82Tone   = Sound[Point]; 
 83Length = Sound[Point+1];    // 读出第一个音符和它时时值
 84
 85LDiv0 = 12000/Speed;    // 算出1分音符的长度(几个10ms)  
 86LDiv4 = LDiv0/4;      // 算出4分音符的长度 
 87LDiv4 = LDiv4-LDiv4*SOUND_SPACE;  // 普通音最长间隔标准 
 88TR0   = 0;
 89TR1   = 1;
 90while(Point < SoundLength)
 91{
 92  SL=Tone%10;         //计算出音符 
 93  SM=Tone/10%10;         //计算出高低音 
 94  SH=Tone/100;         //计算出是否升半 
 95  CurrentFre = NewFreTab[SignTab[SL-1]+SH];  //查出对应音符的频率  
 96  if(SL!=0)
 97  {
 98   if (SM==1) CurrentFre >>= 2;   //低音 
 99   if (SM==3) CurrentFre <<= 2;   //高音
100   Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值
101   Sound_Temp_TH0 = Temp_T/256
102   Sound_Temp_TL0 = Temp_T%256
103   TH0 = Sound_Temp_TH0;  
104   TL0 = Sound_Temp_TL0 + 12//加12是对中断延时的补偿 
105  }

106  SLen=LengthTab[Length%10];  //算出是几分音符
107  XG=Length/10%10;    //算出音符类型(0普通1连音2顿音) 
108  FD=Length/100;
109  LDiv=LDiv0/SLen;    //算出连音音符演奏的长度(多少个10ms)
110  if (FD==1
111   LDiv=LDiv+LDiv/2;
112  if(XG!=1
113   if(XG==0)     //算出普通音符的演奏长度 
114    if (SLen<=4
115     LDiv1=LDiv-LDiv4;
116    else
117     LDiv1=LDiv*SOUND_SPACE;
118   else
119    LDiv1=LDiv/2;   //算出顿音的演奏长度 
120  else
121   LDiv1=LDiv;
122  if(SL==0) LDiv1=0;
123   LDiv2=LDiv-LDiv1;   //算出不发音的长度 
124    if (SL!=0)
125  {
126   TR0=1;
127   for(i=LDiv1;i>0;i--)  //发规定长度的音 
128   {
129    while(TF1==0);
130    TH1 = Sound_Temp_TH1;
131    TL1 = Sound_Temp_TL1;
132    TF1=0;
133   }

134  }

135  if(LDiv2!=0)
136  {
137   TR0=0; BeepIO=1;
138   for(i=LDiv2;i>0;i--)  //音符间的间隔
139   {
140    while(TF1==0);
141    TH1 = Sound_Temp_TH1;
142    TL1 = Sound_Temp_TL1;
143    TF1=0;
144   }

145  }

146  Point+=2
147  Tone=Sound[Point];
148  Length=Sound[Point+1];
149}

150BeepIO = 1;
151}

152//**************************************************************************
153#endif
154
155
156以下为曲谱编码文件,自己可以根据规则,对照简谱编写曲谱编码表,我已经做好了一个应用程序,只需将简谱输入进去,就可以直接输出曲谱编码表,省去人工编码的痛苦。此软件作为共享软件发布,有需要的请留言,此东东绝对是搞电子设计在校大学生泡MM的巨佳手段,呵呵。
157
158附录:
159
160//挥着翅膀的女孩
161unsigned char code Music_Girl[]=0x17,0x020x17,0x030x18,0x030x19,0x020x15,0x03,
162                                  0x16,0x030x17,0x030x17,0x030x17,0x030x18,0x03,
163                                  0x19,0x020x16,0x030x17,0x030x18,0x020x18,0x03,
164                                  0x17,0x030x15,0x020x18,0x030x17,0x030x18,0x02,
165                                  0x10,0x030x15,0x030x16,0x020x15,0x030x16,0x03,
166                                  0x17,0x020x17,0x030x18,0x030x19,0x020x1A,0x03,
167                                  0x1B,0x030x1F,0x030x1F,0x030x17,0x030x18,0x03,
168                                  0x19,0x020x16,0x030x17,0x030x18,0x030x17,0x03,
169                                  0x18,0x030x1F,0x030x1F,0x020x16,0x030x17,0x03,
170                                  0x18,0x030x17,0x030x18,0x030x20,0x030x20,0x02,
171                                  0x1F,0x030x1B,0x030x1F,0x660x20,0x030x21,0x03,
172                                  0x20,0x030x1F,0x030x1B,0x030x1F,0x660x1F,0x03,
173                                  0x1B,0x030x19,0x030x19,0x030x15,0x030x1A,0x66,
174                                  0x1A,0x030x19,0x030x15,0x030x15,0x030x17,0x03,
175                                  0x16,0x660x17,0x040x18,0x040x18,0x030x19,0x03,
176                                  0x1F,0x030x1B,0x030x1F,0x660x20,0x030x21,0x03,
177                                  0x20,0x030x1F,0x030x1B,0x030x1F,0x660x1F,0x03,
178                                  0x1B,0x030x19,0x030x19,0x030x15,0x030x1A,0x66,
179                                  0x1A,0x030x19,0x030x19,0x030x1F,0x030x1B,0x03,
180                                  0x1F,0x000x1A,0x030x1A,0x030x1A,0x030x1B,0x03,
181                                  0x1B,0x030x1A,0x030x19,0x030x19,0x020x17,0x03,
182                                  0x15,0x170x15,0x030x16,0x030x17,0x030x18,0x03,
183                                  0x17,0x040x18,0x0E0x18,0x030x17,0x040x18,0x0E,
184                                  0x18,0x660x17,0x030x18,0x030x17,0x030x18,0x03,
185                                  0x20,0x030x20,0x020x1F,0x030x1B,0x030x1F,0x66,
186                                  0x20,0x030x21,0x030x20,0x030x1F,0x030x1B,0x03,
187                                  0x1F,0x660x1F,0x040x1B,0x0E0x1B,0x030x19,0x03,
188                                  0x19,0x030x15,0x030x1A,0x660x1A,0x030x19,0x03,
189                                  0x15,0x030x15,0x030x17,0x030x16,0x660x17,0x04,
190                                  0x18,0x040x18,0x030x19,0x030x1F,0x030x1B,0x03,
191                                  0x1F,0x660x20,0x030x21,0x030x20,0x030x1F,0x03,
192                                  0x1B,0x030x1F,0x660x1F,0x030x1B,0x030x19,0x03,
193                                  0x19,0x030x15,0x030x1A,0x660x1A,0x030x19,0x03,
194                                  0x19,0x030x1F,0x030x1B,0x030x1F,0x000x18,0x02,
195                                  0x18,0x030x1A,0x030x19,0x0D0x15,0x030x15,0x02,
196                                  0x18,0x660x16,0x020x17,0x020x15,0x000x00,0x00}
;
197//同一首歌
198unsigned char code Music_Same[]=0x0F,0x010x15,0x020x16,0x020x17,0x660x18,0x03,
199                                  0x17,0x020x15,0x020x16,0x010x15,0x020x10,0x02,
200                                  0x15,0x000x0F,0x010x15,0x020x16,0x020x17,0x02,
201                                  0x17,0x030x18,0x030x19,0x020x15,0x020x18,0x66,
202                                  0x17,0x030x19,0x020x16,0x030x17,0x030x16,0x00,
203                                  0x17,0x010x19,0x020x1B,0x020x1B,0x700x1A,0x03,
204                                  0x1A,0x010x19,0x020x19,0x030x1A,0x030x1B,0x02,
205                                  0x1A,0x0D0x19,0x030x17,0x000x18,0x660x18,0x03,
206                                  0x19,0x020x1A,0x020x19,0x0C0x18,0x0D0x17,0x03,
207                                  0x16,0x010x11,0x020x11,0x030x10,0x030x0F,0x0C,
208                                  0x10,0x020x15,0x000x1F,0x010x1A,0x010x18,0x66,
209                                  0x19,0x030x1A,0x010x1B,0x020x1B,0x030x1B,0x03,
210                                  0x1B,0x0C0x1A,0x0D0x19,0x030x17,0x000x1F,0x01,
211                                  0x1A,0x010x18,0x660x19,0x030x1A,0x010x10,0x02,
212                                  0x10,0x030x10,0x030x1A,0x0C0x18,0x0D0x17,0x03,
213                                  0x16,0x000x0F,0x010x15,0x020x16,0x020x17,0x70,
214                                  0x18,0x030x17,0x020x15,0x030x15,0x030x16,0x66,
215                                  0x16,0x030x16,0x020x16,0x030x15,0x030x10,0x02,
216                                  0x10,0x010x11,0x010x11,0x660x10,0x030x0F,0x0C,
217                                  0x1A,0x020x19,0x020x16,0x030x16,0x030x18,0x66,
218                                  0x18,0x030x18,0x020x17,0x030x16,0x030x19,0x00,
219                                  0x00,0x00 }
;
220//两只蝴蝶                                  
221unsigned char code Music_Two[] =0x17,0x030x16,0x030x17,0x010x16,0x030x17,0x03,
222                                  0x16,0x030x15,0x010x10,0x030x15,0x030x16,0x02,
223                                  0x16,0x0D0x17,0x030x16,0x030x15,0x030x10,0x03,
224                                  0x10,0x0E0x15,0x040x0F,0x010x17,0x030x16,0x03,
225                                  0x17,0x010x16,0x030x17,0x030x16,0x030x15,0x01,
226                                  0x10,0x030x15,0x030x16,0x020x16,0x0D0x17,0x03,
227                                  0x16,0x030x15,0x030x10,0x030x15,0x030x16,0x01,
228                                  0x17,0x030x16,0x030x17,0x010x16,0x030x17,0x03,
229                                  0x16,0x030x15,0x010x10,0x030x15,0x030x16,0x02,
230                                  0x16,0x0D0x17,0x030x16,0x030x15,0x030x10,0x03,
231                                  0x10,0x0E0x15,0x040x0F,0x010x17,0x030x19,0x03,
232                                  0x19,0x010x19,0x030x1A,0x030x19,0x030x17,0x01,
233                                  0x16,0x030x16,0x030x16,0x020x16,0x0D0x17,0x03,
234                                  0x16,0x030x15,0x030x10,0x030x10,0x0D0x15,0x00,
235                                  0x19,0x030x19,0x030x1A,0x030x1F,0x030x1B,0x03,
236                                  0x1B,0x030x1A,0x030x17,0x0D0x16,0x030x16,0x03,
237                                  0x16,0x0D0x17,0x010x17,0x030x17,0x030x19,0x03,
238                                  0x1A,0x020x1A,0x020x10,0x030x17,0x0D0x16,0x03,
239                                  0x16,0x010x17,0x030x19,0x030x19,0x030x17,0x03,
240                                  0x19,0x020x1F,0x020x1B,0x030x1A,0x030x1A,0x0E,
241                                  0x1B,0x040x17,0x020x1A,0x030x1A,0x030x1A,0x0E,
242                                  0x1B,0x040x1A,0x030x19,0x030x17,0x030x16,0x03,
243                                  0x17,0x0D0x16,0x030x17,0x030x19,0x010x19,0x03,
244                                  0x19,0x030x1A,0x030x1F,0x030x1B,0x030x1B,0x03,
245                                  0x1A,0x030x17,0x0D0x16,0x030x16,0x030x16,0x03,
246                                  0x17,0x010x17,0x030x17,0x030x19,0x030x1A,0x02,
247                                  0x1A,0x020x10,0x030x17,0x0D0x16,0x030x16,0x01,
248                                  0x17,0x030x19,0x030x19,0x030x17,0x030x19,0x03,
249                                  0x1F,0x020x1B,0x030x1A,0x030x1A,0x0E0x1B,0x04,
250                                  0x17,0x020x1A,0x030x1A,0x030x1A,0x0E0x1B,0x04,
251                                  0x17,0x160x1A,0x030x1A,0x030x1A,0x0E0x1B,0x04,
252                                  0x1A,0x030x19,0x030x17,0x030x16,0x030x0F,0x02,
253                                  0x10,0x030x15,0x000x00,0x00 }
;
254