📄 music.lst
字号:
123 2 if(ch==pn[j])return pf[j];//查表找对应的频率
124 2 j++;
125 2 }
126 1 }
127 /*void display( )
128 {
129 if(minute>0)
130 {
131 Lcd1602_Write_String(1,0,"Time: minute");
132 Lcd1602_Write_Data(1,5,minute/10);
133 Lcd1602_Write_Data(1,6,minute%10);
134 }
135 else if(minute==0)
136 {
137 Lcd1602_Write_String(1,0,"Time: s");
138 Lcd1602_Write_Data(1,6,second/10);
139 Lcd1602_Write_Data(1,7,second%10);
140 }
141 }*/
142 void Play(char * str,uint num)
143 {
144 1 uint lasttime,freq,ch;
145 1 i=num;
146 1 while(1)
147 1 {
148 2 for(;;i++)
149 2 {
150 3 ch=str[i];
151 3
152 3 /*允许曲谱用空格,'|'符,换行,回车等分隔以便阅读*/
153 3 if((ch==' ')||(ch=='|')||(ch=='\r')||(ch=='\n')){i++;continue;}
154 3 if(!ch){SoundOff();return;} /*乐曲结束则播放完毕*/
155 3 if(isdigit(ch)||isalpha(ch))
156 3 {
157 4 freq=GetFreq(ch); /*从音名获取频率*/
158 4 lasttime=256;
159 4 break;
160 4 }
161 3 }
162 2 i++;
163 2 ch=str[i];
164 2 // delay(10); /*从下一个符号获取额外音长符号*/
165 2 while(1)
166 2 {
167 3 if(!ch) break;
168 3 if(isdigit(ch)||isalpha(ch)) break; /*非音长符号则下次处理*/
169 3 if(ch=='-') lasttime +=8; /*额外延时一拍*/
170 3 if(ch=='.') lasttime +=4; /*额外延时半拍*/
171 3 if(ch=='_') lasttime /=2; /*下划线相当于简谱中音名下面的下划线,延时减半*/
172 3 if(ch=='=') lasttime /=4; /*双下划线相当于简谱中音名下面的双下划线,延时减为1/4*/
173 3 i++;
174 3 ch=str[i];
175 3 }
176 2 if(freq!=0)
177 2 {
178 3 Sound(freq); /*发声*/
C51 COMPILER V8.02 MUSIC 04/26/2009 20:56:25 PAGE 5
179 3 flag1++;
180 3 }
181 2 else SoundOff( );
182 2 if(flag1==1)
183 2 {
184 3 ET1=1;
185 3 TR1=1;//播放开始,定时器1开始计时
186 3 }
187 2 delay(lasttime);/*延时*/
188 2 SoundOff( );
189 2 flag1=0;
190 2 ET1=0;
191 2 TR1=0; //播放结束,定时器1停止计时
192 2 //display( );
193 2 second=0; //计时清零
194 2 minute=0;
195 2 delay(50); /*两个音符之间的间歇*/
196 2
197 2 }
198 1 }
199 void keyscan( )//按键选择乐曲类型
200 {
201 1 // EA=0;
202 1 if(key1==0) /*下一曲*/
203 1 {
204 2 delay(5);
205 2 while(key1==0);
206 2 if(order==8)order=0;
207 2 else order++;
208 2 second=0; //歌曲改变,计时清零
209 2 minute=0;
210 2 }
211 1 if(key2==0) /*上一曲*/
212 1 {
213 2 delay(5);
214 2 while(key2==0);
215 2 if(order==0)order=8;
216 2 else order--;
217 2 second=0; //歌曲改变,计时清零
218 2 minute=0;
219 2 }
220 1 }
221
222 void main(void)
223 {
224 1 uint count=20;
225 1 TMOD=0x11; //设定T0为方式1(16位计数)
226 1 delay(10); //T1为方式1(16位计数)
227 1 EA=1;
228 1 IT0=1; //外部中断0:边沿出发---中断标志:IE0
229 1
230 1 ET0=1;
231 1 TR0=1;
232 1
233 1 TH0=0x3C;
234 1 TL0=0xB0;
235 1 TH1=(65536-50000)/256;
236 1 TL1=(65536-50000)%256;
237 1 // Lcd1602_Initial( );
238 1 Play(title[5],i);
239 1 Play(title[8],i);
240 1 while(1)
C51 COMPILER V8.02 MUSIC 04/26/2009 20:56:25 PAGE 6
241 1 {
242 2 keyscan( );
243 2 Play(title[order],i);
244 2 // Play(title[5],i);//调试用所加
245 2 delay(100);
246 2 }
247 1 }
248 void time0_int(void) interrupt 1 //产生方波
249 {
250 1 ET0=0;
251 1 TR0=0;
252 1 TL0=n1;
253 1 TH0=n2;
254 1 Buzz=!Buzz;
255 1 ET0=1;
256 1 TR0=1;
257 1 }
258 void time1_int(void) interrupt 3 //记录播放时间
259 {
260 1 ET1=0;
261 1 TR1=0;
262 1 TH1=(65536-50000)/256;
263 1 TL1=(65536-50000)%256;
264 1 if(count==0)
265 1 {
266 2 count=20;
267 2 if(second==60)
268 2 {
269 3 minute++;
270 3 second=0;
271 3 }
272 2 else second++;
273 2 }
274 1 else count--;
275 1 ET1=1;
276 1 TR1=1;
277 1 }
278 //------外部中断0-----------------------
279 void external_0(void) interrupt 0 //暂停
280 {
281 1 EA=0;
282 1 flag2++; //首次按下暂停
283 1 if(flag2==1)
284 1 {
285 2 temp1=order;//暂停时的歌曲
286 2 temp2=i; //休止符的位置
287 2 TR0=0;
288 2 TR1=0;
289 2 }
290 1 if(flag2==2) //再次按下播放
291 1 {
292 2 order=temp1;
293 2 i=temp2;
294 2 flag2=0;
295 2 TR0=1;
296 2 ET0=1;
297 2 TR1=1;
298 2 ET1=1;
299 2 EA =1;
300 2 }
301 1 }
C51 COMPILER V8.02 MUSIC 04/26/2009 20:56:25 PAGE 7
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 967 ----
CONSTANT SIZE = 6510 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 47 ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -