这个问题有点复杂。一个个地说吧。
首先是音乐的知识:
第一:音乐与频率的关系——标准A = 440 Hz,高8度音的频率为原來音频率的2倍。我们不是搞音乐的,这个就不多说。
第二:音阶与频率的具体关系:
音階 Octave0 Octave1 Octave2 Octave3
Do C 262 523 1047 2093
Db 277 554 1109 2217
Re D 294 587 1175 2349
Eb 311 622 1245 2489
Mi E 330 659 1329 2637
Fa F 349 698 1397 2794
Gb 370 740 1480 2960
Sol G 392 784 1568 3136
Ab 415 831 1661 3322
La A 440 880 1760 3520
Bb 466 923 1865 3729
Si B 494 988 1976 3951
有了这些知识,就可以用单片机控制频率,让蜂鸣器发出音乐了。
怎么编程呢?
给你一个程序:
/*
本实例利用无源蜂鸣器发出音乐声音。
还用到了定时计数器0
*/
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit voice=P1^5;//蜂鸣器I/O口
uchar code sound[]={0xff,
/*
软件使用规则:
下面已经定义好了简谱对应的频率数据
节拍数据为:
四分之一拍:0x10
四分之二拍:0x20
四分之三拍:0x30
一拍:0x40
一又四分之一拍:0x60
两拍:0x80
三拍:0xc0
音乐数据是这样的:两个十六进制数据,表达一个音符,它包含信息有:第一个数据为音阶,第二数据为节拍,一定是成对放置。
*/
//此后为音乐乐谱,全部为3拍
0x60,0xc0,//低音阶1,2,3,4,5,6,7
0x55,0xc0,
0x4c,0xc0,
0x48,0xc0,
0x40,0xc0,
0x39,0xc0,
0x33,0xc0,
0x30,0xc0,//中音阶1,2,3,4,5,6,7
0x2b,0xc0,
0x26,0xc0,
0x24,0xc0,
0x20,0xc0,
0x1c,0xc0,
0x19,0xc0,
0x18,0xc0,//高音阶1,2,3,4,5,6,7
0x15,0xc0,
0x13,0xc0,
0x12,0xc0,
0x10,0xc0,
0x0e,0xc0,
0x0d,0xc0,
0x26,0x20,0x2b,0x20,0x26,0x80,0xff,0x20,0x2b,0x20,0x26,0x20,0x26,0x10,//两只蝴蝶
0x2b,0x10,0x30,0x80,0xff,0x40,0x39,0x20,0x30,0x20,0x2b,0x40,0x2b,0x20,
0x26,0x20,0x2b,0x20,0x30,0x20,0x39,0x20,0x39,0x10,0x30,0x10,0x40,0x80,
0x40,0x80,0x26,0x20,0x2b,0x20,0x26,0x80,0xff,0x20,0x2b,0x20,0x26,0x20,
0x26,0x10,0x2b,0x10,0x30,0x80,0xff,0x40,0x39,0x20,0x30,0x20,0x2b,0x40,
0x2b,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,0x39,0x20,0x30,0x20,0x2b,0xc0,
0x26,0x20,0x2b,0x20,0x26,0x80,0xff,0x20,0x2b,0x20,0x26,0x20,0x26,0x10,
0x2b,0x10,0x30,0xc0,0x39,0x20,0x30,0x20,0x2b,0x40,0x2b,0x20,0x26,0x20,
0x2b,0x20,0x30,0x20,0x39,0x20,0x39,0x10,0x30,0x10,0x40,0xc0,0x26,0x20,
0x20,0x20,0x20,0x80,0xff,0x20,0x20,0x20,0x1c,0x20,0x20,0x20,0x26,0xc0,
0x2b,0x20,0x2b,0x20,0x2b,0x60,0x2b,0x20,0x26,0x20,0x2b,0x20,0x30,0x20,
0x39,0x20,0x39,0x20,0x30,0x20,0x30,0x20,0x30,0xc0,0xff,0x40,0xff,0x40,
0xff,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x18,0x20,0x19,0x20,0x19,0x20,
0x1c,0x20,0x26,0x20,0x2b,0x20,0x2b,0x20,0x26,0x20,0x26,0x80,0xff,0x20,
0x26,0x20,0x26,0x20,0x20,0x20,0x1c,0x40,0x1c,0x40,0xff,0x20,0x39,0x20,
0x26,0x20,0x2b,0x20,0x2b,0xc0,0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x20,
0x20,0x40,0xff,0x20,0x18,0x40,0x19,0x20,0x1c,0x20,0x1c,0x10,0x19,0x10,
0x26,0x40,0xff,0x20,0x1c,0x20,0x1c,0x20,0x19,0x20,0x1c,0x20,0x20,0x20,
0x26,0x20,0x2b,0x20,0xff,0x20,0x26,0x20,0x2b,0x20,0x26,0x20,0x20,0x80,
0xff,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,0x18,0x20,0x19,0x20,0x19,0x20,
0x1c,0x20,0x26,0x20,0x2b,0x20,0x2b,0x20,0x26,0x20,0x26,0x80,0xff,0x20,
0x26,0x20,0x26,0x20,0x20,0x20,0x1c,0x40,0x1c,0x40,0xff,0x20,0x39,0x20,
0x26,0x20,0x2b,0x20,0x2b,0xc0,0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x20,
0x20,0x40,0xff,0x20,0x18,0x40,0x19,0x20,0x1c,0x20,0x1c,0x10,0x19,0x10,
0x26,0x40,0xff,0x20,0x1c,0x20,0x1c,0x20,0x19,0x20,0x1c,0x20,0x20,0x20,
0x26,0x20,0x2b,0x20,0xff,0x20,0x40,0x40,0x39,0x20,0x30,0xc0,0xff,0xc0,
0xff,0xc0,//休止符
,0x00};
uchar zdjs=0, jp;//jp为节拍变量,
void del(yj);//yj为音阶变量,延时为了乐音高低
void main(void)
{
uint dpjs=0;//读数据的指针
uchar yj;
TMOD=0x01;//定时器0,工作方式1:16位定时器(0~65535),定时器模式,由运行控制位TR0开启
IE=0x82;//中断允许寄存器设置,等于以下分别的设置:EA=1总中断允许,ET0=1定时器中断0允许;
TH0=0xd8;//给定时器赋初值,即定时时间的长短:12MHz下10ms
TL0=0xf0;
TR0=1;//启动定时器0
while(1)
{
zdjs=0;//节拍长短的计数器计数变量
dpjs++; yj=sound[dpjs];
dpjs++; jp=sound[dpjs];
while(zdjs!=jp)
{
if(yj!=0xff)
{
if(yj!=0)
{
voice=!voice;
del(yj);
}
else
{
dpjs=0;
break;
}
}
else
{
voice=1;
del(jp);
}
}
}
}
void time0() interrupt 1
{
TH0=0xd8;//定时10ms,12M
TL0=0xf0;
zdjs++;
}
void del(yj)
{
uchar yj2=2;
while(yj!=0)
{
while(yj2!=0)
{
yj2--;
}
yj2=2;
yj--;
}
}
好了,电子音乐已经可以通过51单片机进行演奏了。
还可以有其它的演奏办法:
第一:上述程序不是唯一的,只要能控制好蜂鸣器发声音的频率,就可以发出音乐。
第二:还可以通过电子电路的设计,通过双稳态电路(模拟电路)或其它芯片,可以得到发音乐的结果。小孩玩的电子琴,就是这样来的。网上很多资料,这里不多说了。
|