#include
9 \6 [* q% W, k' l#include
#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
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
}