我自己改了一下
#include"reg52.h"
int tab[]={64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217,65252,65282};
//网上找到的音符与定时器初值对照表中的数据,用来设定时器0初值
sbit bell=P1^3;//位定义蜂鸣器
int i=0; //用于赋定时器0初值
/*延时函数*/
void delay_ms(unsigned int time)
{
unsigned int j;
for(;time>0;time--)
for(j=122;j>0;j--);
}
/*定时器0初始化函数*/
void Timer0_init()
{
TMOD=0x01;//选择定时器0方式1
ET0=1; //开启定时器0中断
EA=1;
TR0=1;
TL0=tab;
TH0=tab>>8;
}
void Timer0_Isp() interrupt 1
{
TL0=tab;
TH0=tab>>8;
bell=!bell;
}
//放音符的数组前面记得加个code,延迟时间凭乐感吧!要关掉蜂鸣器貌似蜂鸣器跟定时器都要关哦,歌曲暂停与播放,强烈推荐用外部中断!
void main()
{
int s=0,len;
//《愿得一人心》的前一部分 网上搜的乐谱,然后填的数据
code char song[]={0,1,1,2,3,3,3,3,3,2,3,5,5,5,2,0,
5,6,7,7,8,8,8,8,3,3,8,7,6,5,0,
5,5,6,8,8,0,
1,1,6,5,6,3,0,
1,2,3,4,4,4,3,4,8,7,8,7,6,5,0,
1,1,2,3,3,3,3,3,2,3,5,6,5,2,0,
5,6,7,8,8,8,8,8,3,3,8,7,6,5,0,
1,1,6,5,6,3,0,
1,2,3,4,4,4,3,4,8,7,8,7,6,5,0,
0,5,5,11,10,9,10,0,//只愿得一人心
10,9,10,12,12,0,
12,12,11,10,9,8,0,
8,8,8,7,8,9,10,0
};
len=sizeof(song);//测量数组字节数,这样就不用数有多少数了
while(1)
{
if(song)
{
i=song-1;
Timer0_init();
Timer0_init();
delay_ms(400);
TR0=0;
delay_ms(50);//使字与字之间产生间隔
TR0=1;
}else
{
TR0=0;
delay_ms(450);
TR0=1;
}
s++;
if(s>=len)
s=0;
}
}
蜂鸣器一端接5V,一端接I/O口就能响,实物响声不大,仿真响声还可以
proteus仿真测试图
|