当前位置:文档之家› 用51单片机实现的音乐程序

用51单片机实现的音乐程序

#include
9 \6 [* q% W, k' l#include - t6 l% u! C P/ v! W7 C8 w5 v4 j/ a
#pragma ot(0)- s/ U& S/ O/ a5 j# i- I
#define uint unsigned int
! x, T8 x/ ?% r# G* h#define uchar unsigned char+ _( o: i$ K q9 h
#define OSFREQ 12000000l //所使用的晶振频率+ _/ Y1 L$ y! z v- `* \; m
$ w8 J( a( N% V3 |
/**************音符频率表****************/& E5 J. Z! M+ Q2 Q
uint code notefreq[]={ 523, 587, 659, 698, 784, 880, 988,
+ _9 ~! I$ V8 V% L
2 l G* H# e. ]5 Q* U! B1 F1047,1175,1319,1396,1568,1760,1976,
$ c. z) S5 x- B
0 I! b1 H/ O9 @4 P6 a7 c2093,2349,2637,2793,3136,3520,3961};1 l( Y% J1 H( `2 N: n3 f) L3 {
/*************音名***************// U! I7 ]" ^ w+ m
uchar code notename[]={'c','d','e','f','g','a','b',
/ O5 C) J5 R$ P7 N; F7 q+ n* B
) m* ~# R4 J$ D' E/ Z2 c '1','2','3','4','5','6','7',
5 e2 B( x3 w$ k* {
: L K& W# F: H& R+ P: S 'C','D','E','F','G','A','B',0};
4 Q# R: I, W4 J5 F/*************半音频率表*****************/- @* P2 x! ~) A$ p
uint code halfnotefreq[]={ 554, 622, 740, 831, 933,
! L4 x6 v4 Z/ z- G6 v. y7 d# X9 W - B. [ o2 S1 S6 I& `: h, E* ]
1109,1245,1480,1161,1865,
. x" @% j4 O+ \& [ 9 Q& F. C T: |6 R) X2 ~9 L( y
2218,2489,2960,3322,3729};4 p& \( e4 _! i- q1 ?- o# Y- |
/*************音名***************/
7 n/ g% h* R. T2 Vuchar code halfnotename[]={'c','d','f','g','a',
# V! o9 }/ H- x0 i
9 v4 s, z3 @" ~9 T/ ~ '1','2','4','5','6',
4 U1 c* i6 ^0 t
& A" u3 n8 O7 N8 Q/ @& n 'C','D','F','G','A',0};
( _% ]+ t& V- ?9 U, I' K/ X, {7 Q! L6 W/ @+ [8 p
sbit BEEP_PWR=P1^0;
5 ]/ s% F1 v5 B$ s# d+ q% y6 g: z% xuchar FreqSandH,FreqSandL; /*产生方波的定时器的初值*/
+ W( L- s) `- B( Y4 Q. G* Ouchar timer1cnt; /*定时器延时计数 */2 x& ]: n5 ~& q0 q0 f% ]
uchar timer1cntflg; /*定时器定时完成标志 */9 `% g S: o; T t; Q2 F1 s

, W! S' r+ B' h- j; f5 ]6 n/*********定时器0用来产生方波***************/
' s" M+ M+ q4 D T9 Jvoid timer0int () interrupt 1
: h+ H. t6 Z* Q% I! q& D/ `1 W{! c# l7 x0 c5 W' h1 C3 x, G2 W9 M
TH0=FreqSandH;
6 C/ U' p, \. } TL0=FreqSandL;
3 q) ?9 o) N( c! Q& { BEEP_PWR=!BEEP_PWR;2 Z8 V7 g8 G3 V
}
+ S1 ~1 j& |, H- s2 K0 a( Y5 t8 Q! ^$ H/ r* F* q' ]) W
/**********定时器用来进行比较准确的延时************/
1 W3 z% M& E) h5 Gvoid timer1int() interrupt 3+ O2 a" _! A) Y5 y
{
; W9 S1 o6 Q; O TH1=0xe0;1 c$ v4 q' X+ v6 @5 D3 m
TL1=0x00;
5 o3 p" _) _0 K2 P timer1cnt++;; m9 t" [1 Z$ G4 p; ^' X
if(timer1cnt>=(OSFREQ/1500000l))( k( ?( J+ D4 J- E9 N& c0 ]: r& n/ B
{timer1cntflg=1; TR1=0;}
5 \1 |- S2 [+ D% B- i7 k}' e+ ?; M& ]# E6 T
- p" {7 j1 |) [
void delay(uchar time)$ x9 T/ L) [8 y: v
{
% J+ }( P4 m/ T0 J5 N: s+ W D- F uchar i;
& C+ \" @. N8 S uint j;
% }; M' o)

L F1 A5 A for(i=0;i! ^8 F2 V( ^# B7 l. }" r1 D; S for(j=0;j<0x900;j++);; U6 ?( C, G1 `
/***7 g3 }( R. l: h% r9 n3 b; {" r" @
uchar i;
' t4 v6 S8 d4 o7 H2 J7 M( r for(i=0;i{timer1cnt=0; timer1cntflg=0;3 g7 J1 ~! h! ]1 I# e. u5 ^" q0 W
TR1=1;
/ S( W, ]6 @0 Z$ b while(!timer1cntflg);
3 \0 ~; H! x/ G& W$ Z7 g }
$ I4 L+ v3 \# w# \9 ]1 q***/
F3 \6 |# ^+ ~8 k; X- {0 i}, g3 y: A9 P: Z& N* p; ]9 B" m- n

$ q- m4 ]" \5 a n5 F* wvoid Sound(uint freq)* K* k' I- U' b$ s1 Q
{
$ p$ P0 C' [& ?* c) [8 M9 @% ?( X uint timreg;0 A, O9 z R+ L- X
timreg=65536l-(OSFREQ/(24l*freq));$ Z/ x) r- D' s! Q4 w
FreqSandH=timreg/256;
0 ~5 e4 q5 e; [; }; L; H) [ FreqSandL=timreg&0x00ff;1 H1 W& D" w6 g+ _
TR0=1; ET0=1;
& [7 M k6 f( }& K+ N% v}$ u( X) M- `! e. e# B! i: E) J* K
/ D% _# g& j" p1 j

* B0 K; M& \2 Wvoid SoundOff(void)3 @( `8 |( Y8 C, c4 p/ n
{/ S) n5 q4 q& Q! o
TR0=0; ET0=0;5 M4 U5 F2 a' p% c) }4 P
BEEP_PWR=0;* `* L( W; z- c* k9 X+ ]
}
) E- M/ o$ W6 t2 W. G% Z& Z# z- T% `5 Y. K1 e3 l+ o
uint GetFreq(uchar ch,uchar flg)5 D- c0 F& z* C: F, J: v6 x" P
{
' z. N3 n& ?1 R; z1 |, Z uchar * pn,i=0;
5 N1 J3 m8 z Z+ u uint * pf;
0 L+ T5 S' q2 s: a. o0 d if(flg) {pn=halfnotename; pf=halfnotefreq;}- o' v2 T/ Y1 h/ M9 i+ \- O* l
else {pn=notename; pf=notefreq;}
( O* @0 O" u: R$ z# l while(1). R' S/ ?5 a5 L% `
{if(pn==0) return 0;
+ K9 c6 I( e6 h- v& ~( D# H if(ch==pn) return pf;8 K1 n: ^$ g) u0 ?& `* D: L( l, d
i++;
; d! W$ Y" Y8 R9 i6 ?5 {+ q8 n& h$ k }
# H5 }, D0 Q5 M}
6 _% ~* h% b' Z1 ~& L o0 O. O% M7 i6 X3 s" E
, P8 n" _: u% R& Kvoid Play(char * str)
|! @1 w6 w( t k5 W: W8 q4 O{& S+ B' M' |) t
uchar i=0,ch,halfflg=0;: y e2 s$ _% N7 b3 C* L& j! h$ i
uchar lasttime;
7 q+ H' Q( F t2 w- f) _ uint freq;
) l0 p2 p& L3 G9 [& N while(1); \" b. ?. {7 t8 `6 D
{for(;;i++)
* S5 S9 l: W3 P* E) i {ch=str; //允许曲谱用空格符 '|'符,换行回车等分隔以
& d4 q4 Z; I# K: Q. u8 p便阅读
; S5 g: L' f4 {& L% k if((ch==' ')||(ch=='|')||(ch=='\r')||(ch=='\n')) {i++; 7 l0 K9 b+ i3 l1 {6 R
continue;}# W6 W9 Y5 N3 Q
if(!ch) {SoundOff(); return;} //乐曲结束则播放完! a* ]8 R* p! T; x! {! A
毕6 u7 @5 t$ C, v/ k& D" E1 p8 G! o
if(ch=='#') {halfflg=1; continue;} //半音标志" ^7 V; h7 U# _8 v7 l
if(isdigit(ch)||isalpha(ch))2 T& [' ^3 j7 h
{freq=GetFreq(ch,halfflg); //从音名获取频率2 X0 c7 m5 _$ v# Q% x2 O' l4 z
lasttime=16;
. e$ _6 o5 p0 d) _: S break;
. s; Q; A: f$ \ }
; u$ x; T, @2 G1 o: E else {halfflg=0; continue;}+ w& I9 ]- y! t
}+ N) E& ?+ _2 a6 q; i+ k
i++;$ f0 l( N9 V$ K' v
ch=str; //从下一个符号获取额外音长符号
6 N$ J1 K/ T5 g8 [. G/ I8 C% ] while(1)( }1 R! L( y- Q2 g3 }. S
{if(!ch) break;
! H) E8 L' G' w

3 W3 Q; f! q( c: a if(isdigit(ch)||isalpha(ch)) break; //非音长符号则下次7 u( o2 {1 K) a" R1 L
处理; U% {" h; g( V; H- X4 R' A+ g
if(ch=='-') lasttime+=8; //额外延时一拍; u5 R+ g; K6 A5 d4 Q6 t; D
if(ch=='.') lasttime+=4; //额外延时半拍
) B: T. x1 t" X& n# |/ n& l if(ch=='_') lasttime/=2; //下划线相当于简谱
. ~. L$ F! e- c. m; w中音名下面的下划线,延时减半8 _& \+ S; o5 w% d2 I
if(ch=='=') lasttime/=4; //双下划线相当于简7 p- W& k! A- N' Y5 p8 w
谱中音名下面的双下划线,延时减为1/41 ~0 r6 S0 {1 e' ^! K% X
i++;
/ A8 O1 E7 d8 W5 _ ch=str;
) c/ o% ]- C D9 n# k, p }
3 b6 O& b! V& \1 A. R/ z if(freq!=0) Sound(freq); //发声: R' d: L' Z& ~/ s6 _5 C+ w5 [6 |2 P$ } F
else SoundOff();
0 ?# l4 B {" m( e3 h* S delay(lasttime); //延时
! R% _! T6 A* C" X. Z8 N+ }6 m! F }5 J K- y0 m" I: V5 F
}

相关主题
文本预览
相关文档 最新文档