#include <reg51.h>
sbit speaker = P0^0;
sbit K0=P2^0;
sbit K1=P2^1;
sbit K2=P2^2;
sbit K3=P2^3;
sbit K4=P2^4;
sbit K5=P2^5;
sbit K6=P2^6;
sbit K7=P2^7;
sbit green=P0^2;
sbit yello=P0^3;
sbit red=P0^4;
unsigned char timer0h, timer0l, time,YG=0,j,k,l=-1;
unsigned long i;
//--------------------------------------
// 频率-半周期数据表 高八位 本软件共保存了四个八度的28个频率数据
unsigned char code Hmusic[32] = {
0xCC,0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567
0xCC,0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, //1,2,3,4,5,6,7,i
0xCC,0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567
0xCC,0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF //超高音 1234567
};
// 频率-半周期数据表 低八位
unsigned char code Lmusic[32] = {
0xCC,0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低音1234567
0xCC,0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, //1,2,3,4,5,6,7,i
0xCC,0x8F, 0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567
0xCC,0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16 //超高音 1234567
};
unsigned char code deng[13]={2
0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD
};
void delay(unsigned char t) //延时程序,控制发音的时间长度
{
unsigned char t1;
unsigned long t2;
for(t1 = 0; t1 < t; t1++) //双重循环, 共延时t个半拍
for(t2 = 0; t2 < 3000; t2++); //延时期间, 可进入T0中断去发音
TR0 = 0; //关闭T0, 停止发音
}
void delay1(unsigned int T) //延时程序,控制发音的时间长度
{
while(T--);
}
//一个音符有三个数字。前为第几个音、中为第几个八度、后为时长(以半拍为单位)。
//6, 2, 3 分别代表:6, 中音, 3个半拍;
//5, 2, 1 分别代表:5, 中音, 1个半拍;
//3, 2, 2 分别代表:3, 中音, 2个半拍;
//5, 2, 2 分别代表:5, 中音, 2个半拍;
//1, 3, 2 分别代表:1, 高音, 2个半拍;
///////////////////////////////////世上只有妈妈好////////////////////////////////////////////
unsigned char code sszymmh[] ={
6, 2, 3, 5, 2, 1, 3, 2, 2, 5, 2, 2, 1, 3, 2, 6, 2, 1, 5, 2,1,
6, 2, 4, 3, 2, 2, 5, 2, 1, 6, 2, 1, 5, 2, 2,3, 2, 2, 1, 2, 1,
6, 1, 1, 5, 2, 1, 3, 2, 1, 2, 2, 4, 2, 2, 3, 3, 2, 1, 5,2, 2,
5, 2, 1, 6, 2, 1, 3, 2, 2, 2, 2, 2, 1, 2, 4,5,2,6,3,2,2,2,2,2,
1,2,2,6,1,2,1,2,2,5,1,8,0,0,0
};
///////////////////////////////////////////新年好/////////////////////////////////////////////////////////
unsigned char code xnh[] ={
1,2,1,1,2,1,1,2,2,5,1,2,3,2,1,3,2,1,3,2,2,1,2,2,1,2,1,3,2,1,5,2,2,
5,2,2,4,2,1,3,2,1,2,2,4,2,2,1,3,2,1,4,2,2,4,2,2,3,2,1,2,2,1,3,2,2,
1,2,2,1,2,1,3,2,1,2,2,2,5,1,2,7,1,1,2,2,1,1,2,4,0,0,0
};
//////////////////////////////////////外婆的澎湖湾//////////////////////////////////////////////////////
unsigned char code wpdphw[]={
3,1,2,5,1,2,5,1,2,5,1,2,6,1,1,1,2,3,6,1,2,5,1,2,1,2,2,1,2,2,6,1,2,
6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,4,2,2,3,2,2,2,2,1,1,2,3,2,2,1,
2,2,1,2,2,1,2,2,1,2,2,2,3,2,2,2,2,8,3,2,2,3,2,2,3,2,2,3,2,1,3,2,1,
4,2,2,3,2,2,2,2,1,1,2,3,6,1,2,1,2,2,1,2,2,6,1,2,5,1,8,3,2,2,3,2,2,
3,2,2,3,2,1,3,2,1,4,2,2,3,2,2,2,2,1,1,2,3,5,1,1,5,1,1,5,1,1,5,1,1,
2,2,1,1,2,1,7,1,2,1,2,8,3,1,2,5,1,2,5,1,2,5,1,2,6,1,1,1,2,3,6,1,2,
5,1,2,1,2,2,1,2,1,1,2,1,6,1,2,6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,
4,2,2,3,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,1,2,2,2,3,2,2,2,2,8,3,2,2,
3,2,2,3,2,2,3,2,1,3,2,1,4,2,2,3,2,2,2,2,2,1,2,2,6,1,2,1,2,1,1,2,1,
6,1,2,6,1,2,5,1,8,3,2,2,3,2,2,3,2,2,3,2,2,4,2,2,3,2,2,2,2,2,1,2,2,
5,1,2,5,1,2,2,2,1,1,2,1,7,1,2,1,2,8,7,1,4,7,1,2,1,2,2,2,2,4,5,1,4,
1,2,2,5,1,2,1,2,2,2,2,2,3,2,4,1,2,4,4,2,2,4,2,4,3,2,2,2,2,2,1,2,2,
7,1,2,1,2,2,2,2,6,3,2,2,2,2,8,3,2,6,3,2,2,4,2,4,4,2,3,4,2,1,3,2,3,
2,2,1,1,2,2,7,1,2,6,2,8,5,1,2,5,1,2,0,1,2,1,2,2,1,2,2,0,1,2,2,2,4,
1,2,4,2,2,4,1,2,2,2,2,2,3,2,8,5,2,4,4,2,4,3,2,6,1,2,2,7,1,4,1,2,2,
2,2,2,0,0,0
};
//////////////////////////////////时间煮雨///////////////////////////////////////////////////////////
unsigned char code sjzy[]={
0,1,4,3,2,2,3,2,2,2,2,6,7,1,2,7,1,2,1,2,2,1,2,4,0,1,1,0,1,1,0,1,1,
3,2,2,3,2,2,2,2,2,1,2,2,2,2,2,5,2,2,5,2,2,3,2,2,3,2,8,0,1,1,0,1,1,
6,2,2,6,2,2,5,2,4,3,2,2,2,2,2,3,2,4,2,2,4,1,2,8,3,2,4,2,2,2,1,2,2,
2,2,6,7,1,2,7,1,2,6,1,2,6,1,8,0,1,1,0,1,1,3,2,2,3,2,2,2,2,6,7,1,2,
7,1,2,1,2,2,1,2,8,0,1,1,0,1,1,3,2,2,3,2,2,2,2,2,1,2,2,2,2,2,5,2,2,
5,2,2,3,2,2,3,2,8,0,1,2,0,1,1,6,2,2,6,2,2,5,2,4,3,2,2,2,2,2,3,2,4,
2,2,4,1,2,8,3,2,4,2,2,2,1,2,2,2,2,6,1,2,2,1,2,8,0,1,1,0,1,1,3,2,2,
5,2,2,6,2,4,1,3,4,7,2,6,5,2,2,3,2,4,0,1,1,1,2,2,1,2,6,6,2,2,6,2,2,
5,2,2,3,2,2,2,2,2,3,2,8,0,1,1,0,1,1,0,1,1,3,2,2,5,2,2,6,2,4,1,3,4,
7,2,6,3,2,2,1,3,4,0,1,1,3,2,2,2,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,
1,2,2,1,2,2,1,2,8,0,1,1,1,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,2,2,2,
3,2,2,0,1,2,3,2,2,5,2,2,6,2,6,1,3,2,7,2,4,3,2,4,1,3,4,0,1,1,3,2,2,
2,2,6,6,2,2,6,2,2,5,2,2,3,2,2,2,2,2,1,2,2,1,2,2,1,2,8,0,1,1,0,1,4,
3,2,2,5,2,2,6,2,4,1,3,4,7,2,6,3,2,2,2,3,2,1,3,2,0,1,1,3,2,2,2,2,6,
6,2,2,6,2,2,5,2,2,3,2,4,2,2,1,1,2,1,1,2,2,1,2,8,0,2,2,0,0,0
};
//////////////////////////////猪八戒背媳妇/////////////////////////////////
unsigned char code zbjbxf[]={
6,2,4,3,3,3,5,3,1,3,3,2,6,2,2,1,3,4,6,2,1,1,3,1,6,2,1,1,3,1,
3,3,4,3,3,1,2,3,1,3,3,1,1,3,1,6,2,4,3,3,3,5,3,1,6,3,2,6,3,2,
6,3,2,3,3,2,5,3,4,3,3,1,5,3,1,3,3,1,5,3,1,6,3,2,6,3,2,6,3,2,
3,3,2,5,3,4,5,3,2,6,2,2,5,3,2,6,2,2,3,3,1,2,3,1,3,3,1,1,3,4,
2,3,4,2,3,4,2,3,2,1,3,1,2,3,1,3,3,2,5,3,2,6,3,4,3,4,4,3,3,4,
3,4,4,3,3,2,3,4,2,3,3,2,3,4,2,3,3,1,2,3,1,3,3,1,1,3,4,2,3,4,
2,3,4,2,3,2,1,3,1,2,3,1,3,3,2,5,3,2,6,3,8,0,0,0
};
////////////////////////////////宾克斯的酒///////////////////////////////
unsigned char code bksdj[]={
3,2,4,5,2,2,5,2,2,5,2,8,6,2,2,5,2,2,3,2,4,5,2,8,3,2,4,5,2,2,
5,2,2,5,2,8,6,2,2,5,2,2,3,2,4,1,2,8,3,2,4,5,2,2,5,2,2,5,2,8,
6,2,2,5,2,2,3,2,4,5,2,8,3,2,4,5,2,2,5,2,2,5,2,8,6,2,2,5,2,2,
3,2,4,1,2,8,5,2,3,3,2,1,2,2,2,1,2,2,6,1,3,7,1,1,1,2,4,5,2,3,
3,2,1,2,2,2,1,2,2,6,1,3,1,2,1,5,1,4,6,1,3,1,2,1,5,1,4,6,1,3,
7,1,1,1,2,4,3,2,4,3,2,3,3,2,1,2,2,4,1,2,3,2,2,1,5,2,3,3,2,1,
2,2,2,1,2,2,6,1,3,7,1,1,1,2,4,5,2,3,3,2,1,2,2,2,1,2,2,6,1,3,
1,2,1,5,1,4,6,1,3,1,2,1,5,1,4,6,1,3,7,1,1,1,2,4,3,2,4,3,2,3,
1,2,1,2,2,4,1,2,12,0,0,0
};
void yingao();
void keyscan();
void dupu();
void song();
void panduan();
void zanting();
void liushui();
void xuange();
void main()
{
TMOD = 1; //置T0定时工作方式1
ET0 = 1; //开T0中断
EA = 1; //开CPU中断
IT0=1;
EX0=1;
while(1)
{
keyscan();
dupu();
}
}
void ex0_int() interrupt 0
{
time=0;
}
void t0int() interrupt 1 //T0中断程序,控制发音的音调
{
TR0 = 0; //先关闭T0
if(timer0h ==0xcc&&timer0l==0xcc)
speaker=1;
else
speaker = !speaker; //输出方波, 发音
TH0 = timer0h; //下次的中断时间, 这个时间, 控制音调高低
TL0 = timer0l;
TR0 = 1; //启动T0
}
void panduan()
{
if(YG==1)
{
green=0;
yello=1;
red=1;
}
if(YG==2)
{
green=1;
yello=0;
red=1;
}
if(YG==3)
{
green=1;
yello=1;
red=0;
}
if(YG==4)
{
red=0;
green=1;
yello=0;
}
}
void keyscan()
{
if(!K0) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K0) //再次判断按键0是否确实按下
{
YG++; //如果是LED1亮
panduan();
while(!K0); //等待按键0弹起
}
}
///////////////////////////////////////////////////////////////////////
if((!K1)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K1) //再次判断按键0是否确实按下
{
j=1;
yingao();
while(!K1); //等待按键0弹起
TR0=0;
}
}
/////////////////////////////////////////////////////////////////////
if((!K2)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K2) //再次判断按键0是否确实按下
{
j=2;
yingao();
while(!K2); //等待按键0弹起
TR0=0;
}
}
/////////////////////////////////////////////////////////
if((!K3)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K3) //再次判断按键0是否确实按下
{
j=3;
yingao();
while(!K3); //等待按键0弹起
TR0=0;
}
}
//////////////////////////////////////////////////////////////
if((!K4)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K4) //再次判断按键0是否确实按下
{
j=4;
yingao();
while(!K4); //等待按键0弹起
TR0=0;
}
}
////////////////////////////////////////////////////////////
if((!K5)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K5) //再次判断按键0是否确实按下
{
j=5;
yingao();
while(!K5); //等待按键0弹起
TR0=0;
}
}
///////////////////////////////////////////////////////////
if((!K6)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K6) //再次判断按键0是否确实按下
{
j=6;
yingao();
while(!K6); //等待按键0弹起
TR0=0;
}
}
////////////////////////////////////////////////////////////////
if((!K7)&&(YG<=4)) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K7) //再次判断按键0是否确实按下
{
j=7;
yingao();
while(!K7); //等待按键0弹起
TR0=0;
}
}
}
void yingao()
{
timer0l=Lmusic[j+8*(YG-1)];
timer0h=Hmusic[j+8*(YG-1)];
TH0=timer0h;
TL0=timer0l;
TR0=1;
}
void song() //演奏一个音符
{
TH0 = timer0h; //控制音调
TL0 = timer0l;
TR0 = 1; //启动T0, 由T0输出方波去发音
delay(time); //控制时间长度
}
void dupu()
{
while(YG>4)
{
green=0;
yello=0;
red=0;
YG++;
if(YG==12)
{
YG=0;
time=0;
P0=0X1D;
P2=0XFF;
}
else
time=1;
delay1(40000);
i = 0;
while(time)
{
xuange();
//第i个是音符, 第i+1个是第几个八度
timer0h = Hmusic[k]; //从数据表中读出频率数值
timer0l = Lmusic[k]; //实际上, 是定时的时间长度
//读出时间长度数值
i=i+3;
song(); //发出一个音符
zanting();
liushui();
}
}
}
void zanting()
{
if(!K0) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K0) //再次判断按键0是否确实按下
{
while(!K0);
while(1)
{
if(!K0) //判断按下的是否是按键0
{
delay1(200); //消抖
if(!K0) //再次判断按键0是否确实按下
{
while(!K0);
break;
}
}
}
}
}
}
void liushui()
{
l++;
if(l==13)
l=0;
P2=deng[l];
}
void xuange()
{
if(YG==6)
{
k = sszymmh[i] + 8 * (sszymmh[i+1] - 1);
time = sszymmh[i + 2];
}
if(YG==7)
{
k = xnh[i] + 8 * (xnh[i+1] - 1);
time = xnh[i + 2];
}
if(YG==8)
{
k = zbjbxf[i] + 8 * (zbjbxf[i+1] - 1);
time = zbjbxf[i + 2];
}
if(YG==9)
{
k =bksdj[i] + 8 * (bksdj[i+1] - 1);
time = bksdj[i + 2];
}
if(YG==10)
{
k = wpdphw[i] + 8 * (wpdphw[i+1] - 1);
time = wpdphw[i + 2];
}
if(YG==11)
{
k = sjzy[i] + 8 * (sjzy[i+1] - 1);
time = sjzy[i + 2];
}
}
|