让FS2410“裸奔”着唱歌
【编译环境】windows xp
【目标机】FS2410
【交叉编译器】Keil RealView MDK ARM 3.50
这段时间在学《ARM嵌入式体系结构与接口技术》,实验课就把FS2410当作一个单片机来捣鼓,让蜂鸣器奏乐在8位的51单片机上玩过,而在32位的平台上确实没有搞过,不过,蜂鸣器还是那种蜂鸣器,乐曲还是那么几个调,大同小异罢了,只要能把声音的频率和时长控制了,就能随心所欲放什么曲子了。
首先明确7个音名的频率:C (261.6256Hz) 、D(293.6648Hz)、E(329.6276)、F(349.2282Hz)、G(391.9954Hz)、A(440Hz国际标准音)、B(493.8833Hz)。
实际上FS2410无法完全达到上述精确频率,只要接近就可以了,一般人是听不出什么差异来的,所以,C大调我给各唱名定的频率是:
1. #define DO 262
2. #define RE 294
3. #define MI 330
4. #define FA 349
5. #define SOL 392
6. #define LA 440
7. #define SI 494
D大调的频率是:
1. #define DO 293
2. #define RE 330
3. #define MI 370
4. #define FA 349
5. #define SOL 440
6. #define LA 494
7. #define SI 554
低一个8度就在对应的唱名频率上除以2,高一个8度把对应频率乘以2。下面给出的是我实现了的三首曲子:
#define BIG_D
typedef struct
{
int pitch;
int dimation;
}Note;
//C大调
#ifdef BIG_C
#define DO 262
#define RE 294
#define MI 330
#define FA 349
#define SOL 392
#define LA 440
#define SI 494
#define TIME 6000
#endif
//D大调
#ifdef BIG_D
#define DO 293
#define RE 330
#define MI 370
#define FA 349
#define SOL 440
#define LA 494
#define SI 554
#define TIME 6000
#endif
//---------《世上只有妈妈好》电影妈妈再爱我一次--------------
Note MumIsTheBestInTheWorld[]= {
//6. //_5 //3 //5
{LA,TIME+TIME/2}, {SOL,TIME/2},{MI,TIME},{SOL,TIME},
//1^ //6_ //_5 //6-
{DO*2,TIME},{LA,TIME/2},{SOL,TIME/2} ,{LA,2*TIME},
//3 //5_ //_6 //5
{MI,TIME},{SOL,TIME/2},{LA,TIME/2},{SOL,TIME},
//3 //1_ //_6,
{MI,TIME},{DO,TIME/2},{LA/2,TIME/2},
//5_ //_3 //2- //2.
{SOL,TIME/2},{MI,TIME/2},{RE,TIME*2},{RE,TIME+TIME/2},
//_3 //5 //5_ //_6
{MI,TIME/2},{SOL,TIME},{SOL,TIME/2},{LA,TIME/2},
//3 //2 //1- //5.
{MI,TIME},{RE,TIME},{DO,TIME*2},{SOL,TIME+TIME/2},
//_3 //2_ //_1 //6,_
{MI,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME/2},
//_1 //5,--
{DO,TIME/2},{SOL/2,TIME*3}
};
//--------------《大长今》韩国古装片-------------------
Note GreatlyLongNow[]={
//2 3 3 3. _2 1
{RE,TIME}, {MI,TIME},{MI,TIME},{MI,TIME+TIME/2},{RE,TIME/2},{DO,TIME},
//6, 1 2 1-- 2 3 3
{LA/2,TIME},{DO,TIME},{RE,TIME},{DO,TIME*3},{RE,TIME},{MI,TIME},{MI,TIME},
//3. _5 3 3 2 3
{MI,TIME+TIME/2},{SOL,TIME/2},{MI,TIME},{MI,TIME},{RE,TIME},{MI,TIME},
//3-- 5 6 6 6. _5
{MI,TIME*3},{SOL,TIME},{LA,TIME},{LA,TIME},{LA,TIME+TIME/2},{SOL,TIME/2},
//3 3 5 6 5--- 2 3
{MI,TIME},{MI,TIME},{SOL,TIME},{LA,TIME},{SOL,TIME*3},{RE,TIME},{MI,TIME},
//3 2. _3 3 2 3
{MI,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{MI,TIME},{RE,TIME},{MI,TIME},
//6, 1_ _6, 6,-
{LA/2,TIME},{DO,TIME/2},{LA/2,TIME/2},{LA/2,TIME*2},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//2 3 1 2. _3 5
{RE,TIME},{MI,TIME},{DO,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{SOL,TIME},
//6_ _6 6_ _5 3
{LA,TIME/2},{LA,TIME/2},{LA,TIME/2},{SOL,TIME/2},{MI,TIME},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//6, 5,. _6, 6,--
{LA/2,TIME},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{LA/2,TIME*3},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//2 3 1 2. _3 5
{RE,TIME},{MI,TIME},{DO,TIME},{RE,TIME+TIME/2},{MI,TIME/2},{SOL,TIME},
//6_ _6 6_ _5 3
{LA,TIME/2},{LA,TIME/2},{LA,TIME/2},{SOL,TIME/2},{MI,TIME},
//2_ _2 2_ _1 6,
{RE,TIME/2},{RE,TIME/2},{RE,TIME/2},{DO,TIME/2},{LA/2,TIME},
//6, 5,. _6, 6,--
{LA/2,TIME},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{LA/2,TIME*3}
};
//------------《渔舟唱晚》央视天气预报背景音乐-----------------
Note FishBoat[]={ //3. _5 6._ =1^ 6_
{MI,TIME+TIME/2},{SOL,TIME/2},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},
/ /_5 3 -. 2 1. _3 2._
{SOL,TIME/2},{MI,TIME*3},{RE,TIME},{DO,TIME+TIME/2},{MI,TIME/2},{RE,TIME/2+TIME/4},
//=3 2_ _1 2-- 3. _5
{MI,TIME/4},{RE,TIME/2},{DO,TIME/2},{RE,TIME*4},{MI,TIME+TIME/2},{SOL,TIME/2},
//2 1 6._ =1^ 6_ _5
{RE,TIME},{DO,TIME},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},{SOL,TIME/2},
//6- 5,. _6, 1._ =3
{LA,TIME*2},{SOL/2,TIME+TIME/2},{LA/2,TIME/2},{DO,TIME/2+TIME/4},{MI,TIME/4},
//2_ _1 5,--
{RE,TIME/2},{DO,TIME/2},{SOL/2,TIME*4},
//3. _5 6._ =1^ 6_
{MI,TIME+TIME/2},{SOL,TIME/2},{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},
//_5 3-. 5_ _6 1^_ _6
{SOL,TIME/2},{MI,TIME*3},{SOL,TIME/2},{LA,TIME/2},{DO*2,TIME+TIME/2},{LA,TIME/2},
//5._ =6 5_ _3 2--
{SOL,TIME/2+TIME/4},{LA,TIME/4},{SOL,TIME/2},{MI,TIME/2},{RE,TIME*4},
//3. _5 2._ =3 2_ _1
{MI,TIME+TIME/2},{SOL,TIME/2},{RE,TIME/2+TIME/4},{MI,TIME/4},{RE,TIME/2},{DO,TIME/2},
//6._ =1^ 6_ _5 6- 1.
{LA,TIME/2+TIME/4},{DO*2,TIME/4},{LA,TIME/2},{SOL,TIME/2},{LA,TIME*2},{DO,TIME+TIME/2},
//_2 3_ _5 2_ _3 1--
{RE,TIME/2},{MI,TIME/2},{SOL,TIME/2},{RE,TIME/2},{MI,TIME/2},{DO,TIME*4}
};
/*********************************************************************************
* name: beep_play
* func:
* modify:
* comment:
**********************************************************************************/
void beep_play(void)
{
int i,div;
rGPBCON =(rGPBCON&(~0x03))+2; //set GPBO TOUT0
rTCFG0 = (rTCFG0&(~0xff))+255; //prescaler = 255
rTCFG1 = (rTCFG1&(~0x0f))+0x01; //mux = 1/4;
//Mum Is The Best In The World
for(i = 0;i<sizeof(MumIsTheBestInTheWorld)/sizeof(Note);i++ )
{
div = (PCLK/256/4)/(MumIsTheBestInTheWorld[i].pitch);
rTCNTB0 = div; //freq 这一步控制声音的频率
rTCMPB0 = (2*div)/3;//pwm 这一步控制声音的大小
rTCON = 0xa; //manual
rTCON = 0x9; //start
delay((MumIsTheBestInTheWorld[i].dimation)); //这一步控制声音的时长
rTCON = 0x0; //stop
}
delay(20000);
//Greatly Long Now
for(i = 0;i<sizeof(GreatlyLongNow)/sizeof(Note);i++ )
{
div = (PCLK/256/4)/(GreatlyLongNow[i].pitch);
rTCNTB0 = div; //freq
rTCMPB0 = (2*div)/3;//pwm
rTCON = 0xa; //manual
rTCON = 0x9; //start
delay((GreatlyLongNow[i].dimation));
rTCON = 0x0; //stop
}
delay(20000);
//Fish boat
for(i = 0;i<sizeof(FishBoat)/sizeof(Note);i++ )
{
div = (PCLK/256/4)/(FishBoat[i].pitch);
rTCNTB0 = div; //freq
rTCMPB0 = (2*div)/3;//pwm
rTCON = 0xa; //manual
rTCON = 0x9; //start
delay((FishBoat[i].dimation));
rTCON = 0x0; //stop
}
}
听着蜂鸣器沙哑而优美的曲子,倒是别有一番风味,要不再整首《beat it》?