#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar key,a;
sbit P2_0=P2^0;
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit k4=P3^3;
uchar STH0,STL0,STH1,STL1;
uchar timer0h,timer0l; //下次的中断时间, 这个时间, 控制音调高低
uchar i,time,k;
unsigned char code key_code[]={0xee,0xed,0xeb,0xe7,0xde,
0xdd,0xdb,0xd7,0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77};
unsigned int code tab[]={63628,63835,64103,64260,64331,64400,64524,64580,
64021,64103,64260,64400,64524,64580,64684,64777};//简谱码(T值)
code unsigned char FREQH[] = {
0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567
0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};
code unsigned char FREQL[] = {
0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低音1234567
0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567
0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};
code unsigned char zhenai[] = //真的爱你
{
5,2,2, 1,3,2, 2,3,2, 2,3,1, 3,3,3, 3,3,1, 2,3,1, 1,3,1, 2,3,1, 2,3,5, 2,3,1, 3,3,1,
2,3,2, 1,3,2, 7,2,1, 1,3,1, 7,2,2, 6,2,5, 1,3,1, 2,3,1, 2,3,1, 3,3,3, 3,3,1, 2,3,1,
1,3,1, 2,3,1, 2,3,4, 2,3,1, 1,3,1, 7,2,1, 1,3,3, 5,2,1, 1,3,1, 5,3,1, 7,2,1, 1,3,1,
5,3,2, 1,3,2, 1,3,2, 2,3,2,
2,3,1, 3,3,3, 3,3,1, 2,3,1, 1,3,1, 2,3,1, 2,3,5, 2,3,1, 3,3,1, 2,3,2, 1,3,2, 7,2,1,
1,3,1, 7,2,2, 6,2,6, 1,3,1, 2,3,1, 2,3,1, 3,3,3, 3,3,1, 2,3,1, 1,3,1, 2,3,1, 2,3,4,
2,3,1, 1,3,1, 7,2,1, 1,3,1, 1,3,4, 5,2,2, 4,2,2, 3,2,2, 5,1,2,
0,0,0,
};
code unsigned char sui[] = //岁月无声
{
1,2,6, 1,2,2, 2,2,2, 3,2,2, 1,2,2, 4,2,6, 4,2,2, 3,2,2, 2,2,2, 1,2,2, 7,1,6,
7,1,2, 1,2,2, 7,1,2, 5,1,2, 6,2,3, 5,2,1, 4,2,2, 3,2,2, 5,2,1, 4,2,1, 3,2,1, 2,2,1,
4,2,1, 3,2,1, 2,2,1, 7,1,1, 1,2,6, 1,2,2, 2,2,2, 3,2,2, 1,2,2, 4,2,6,
4,2,2, 3,2,2, 2,2,2, 1,2,2, 7,1,6, 7,1,2, 1,2,2, 7,1,2, 5,1,2, 6,2,3, 5,2,1,
4,2,2, 3,2,2, 5,2,1, 4,2,1, 3,2,1, 2,2,1, 4,2,1, 3,2,1, 2,2,1, 7,1,1, 1,2,6,
1,2,2, 7,1,2, 1,2,2, 2,2,2, 3,2,6, 2,2,6, 0,0,0,
};
code unsigned char hua[] = //蓝莲花
{
5,1,2, 6,1,2, 1,2,2, 2,2,2, 3,2,2, 2,2,4, 1,2,2, 6,1,6,
5,1,2, 6,1,2, 1,2,2, 2,2,2, 3,2,2, 5,2,4, 2,2,6,
2,2,4, 5,1,2, 2,2,2, 2,2,2, 3,2,2, 2,2,2, 1,2,6,
2,2,2, 2,2,2, 2,2,2, 5,1,2, 6,1,2, 1,2,2, 6,1,6,
4,2,4, 4,2,2, 3,2,2, 2,2,2, 1,2,2, 3,2,2, 2,2,6,
4,2,4, 6,2,2, 5,2,2, 4,2,2, 3,2,2, 2,2,6,
2,2,4, 5,1,2, 2,2,2, 2,2,2, 3,2,2, 2,2,2, 1,2,6,
2,2,2, 2,2,2, 2,2,2, 5,1,2, 6,1,2, 1,2,2, 6,1,6,
5,2,2, 5,2,2, 5,2,2, 5,2,2, 5,2,2, 5,2,2, 6,2,3, 6,2,6,
6,2,2, 6,2,2, 1,3,2, 6,2,2, 6,2,2, 5,2,6,
5,2,2, 5,2,2, 5,2,2, 5,2,2, 6,2,2, 1,3,2, 6,2,6,
5,2,2, 6,2,2, 3,3,6, 2,3,6, 0,0,0,
};
code unsigned char wmong[] = //我们能不能不分手
{
1,3,1, 7,2,1, 6,2,2, 3,3,1, 2,3,3, 5,2,2, 2,3,1, 1,3,3,
3,2,2, 1,3,1, 7,2,2, 6,2,3, 5,2,4,
6,2,3, 5,2,1, 6,2,1, 7,2,2, 3,2,2, 1,3,3, 7,2,1, 1,3,1,
3,3,3, 3,3,1, 3,3,1, 1,3,1, 1,3,1, 6,2,1, 5,2,3, 2,3,3,
1,3,6,
1,3,1, 7,2,1, 6,2,1, 5,2,3, 2,2,1, 3,2,4, 5,2,1, 1,2,4,
1,3,1, 7,2,1, 6,2,1, 5,2,3, 2,2,1, 3,2,4,
1,3,1, 7,2,1, 6,2,1, 5,2,3, 2,2,1, 3,2,4, 5,2,1, 1,2,4, 5,2,1,
1,3,1, 7,2,1, 6,2,2, 3,3,1, 2,3,3, 5,2,2, 2,3,1, 1,3,3,
3,2,2, 1,3,1, 7,2,2, 6,2,3, 5,2,4,
6,2,2, 5,2,1, 6,2,1, 7,2,2, 3,2,2, 1,3,2, 7,2,1, 1,3,1,
3,3,2, 5,2,1, 3,3,1, 1,3,1, 1,3,1, 6,2,1, 5,2,2, 2,3,2, 1,3,6, 0,0,0
} ;
//第一个数字是音符的数值1234567之一,代表多来咪发...
//第二个数字是0123之一,代表低音、中音、高音、超高音
//第三个数字是时间长度,以半拍为单位
//乐曲数据表的结尾是三个0
//==========延时=============
void delayms(uint ms)
{
uchar t;
while(ms--)
{
for(t=0;t<120;t++);
}
}
//==============开关识别===========================
uchar keyscan()
{
uchar scan1,scan2,keycode,j;
P1=0xf0;
scan1=P1;
if((scan1&0xf0)!=0xf0)
{
delayms(30);
scan1=P1;
if((scan1&0xf0)!=0xf0)
{
P1=0x0f;
scan2=P1;
keycode=scan1|scan2;
for(j=0;j<=15;j++)
{
if(keycode==key_code[j])
{
key=j;
return(key);
}
}
}
}
else P1=0xff;
return(16);
}
//============开关的读取==============
void keydown()
{
P1=0x0f;
if((P1&0x0f)!=0x0f)
{
keyscan();
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
while((P1&0x0f)!=0x0f);
if((P1&0x0f)==0x0f)
{
TR0=0;
}
}
}
//============================================================
void delay(unsigned char t) //延时程序,控制发音的时间长度
{
unsigned char t1;
unsigned long t2;
for(t1=0;t1<t;t1++) //双重循环, 共延时t个半拍
for(t2=0;t2<5000;t2++); //延时期间, 可进入T1中断去发音
TR1 = 0; //关闭T1, 停止发音
}
void song() //演奏一个音符
{
TH1 = timer0h; //控制音调
TL1 = timer0l;
TR1 = 1; //启动T1, 由T1输出方波去发音
delay(time); //控制时间长度
}
//======================歌曲子函数 ===========
void gequ1()
{
if(!k1)
{
while(time)
{
k=zhenai[i]+7*zhenai[i+1]-1;//第i个是音符, 第i+1个是第几个八度
timer0h=FREQH[k]; //从数据表中读出频率数值
timer0l=FREQL[k]; //实际上, 是定时的时间长度
time=zhenai[i+2]; //读出时间长度数值
i+=3;
song();//发出一个音符
}
}
}
//===================歌曲2=============
void gequ2()
{
if(!k2)
{
while(time)
{
k=sui[i]+7*sui[i+1]-1;
timer0h=FREQH[k];
timer0l=FREQL[k];
time=sui[i+2];
i+=3;
song();
}
}
}
//===================歌曲3=============
void gequ3()
{
if(!k3)
{
while(time)
{
k=hua[i]+7*hua[i+1]-1;
timer0h=FREQH[k];
timer0l=FREQL[k];
time=hua[i+2];
i+=3;
song();
}
}
}
//===================歌曲4=============
void gequ4()
{
if(!k4)
{
while(time)
{
k=wmong[i]+7*wmong[i+1]-1;
timer0h=FREQH[k];
timer0l=FREQL[k];
time=wmong[i+2];
i+=3;
song();
}
}
}
//===================
main()//主函数
{
TMOD=0X11;//选择工作方式
ET0=1;//允许T0工作
ET1=1;//允许T1工作
EA=1;
i=0;
time=1;
while(1)
{
keydown();
gequ1();
gequ2();
gequ3();
gequ4();
delayms(5);
}
}
//===================中断
void t0(void) interrupt 1//中断
{
TH0=STH0;
TL0=STL0;
P2_0=~P2_0;
}
void t0int() interrupt 3 //T1中断程序,控制发音的音调
{
TR1=0; //先关闭T1
P2_0=~P2_0; //输出方波, 发音
TH1=timer0h; //下次的中断时间, 这个时间, 控制音调高低
TL1=timer0l;
TR1=1; //启动T0
}
/*
void t1() interrupt 0
{
delayms(10);
if(INT0==0)
{
time=1;
a++;
if(a>6)a=1;
}
}
*/
评论0