#include<reg52.h>
#define keyport P1
#define uchar unsigned char
#define uint unsigned int
uchar high,low; //定时器预装值的高8位和低8位
sbit speak=P3^0;
sbit gao=P3^5;
sbit di=P3^6;
sbit zdbf=P3^7;
uchar yinjie=1;
uchar time;
uchar n=0;
uchar bo=0;
uchar code fre[][2]= {
0x8c,0xf8,
0x5b,0xf9,
0x15,0xfa,
0x67,0xfa,
0x90,0xfb,
0xae,0xfb,
0x0c,0xfc, //低音
0x44,0xfc,
0xac,0xfc,
0x09,0xfd,
0x34,0xfd,
0x82,0xfd,
0xc2,0xfd,
0x06,0xfe, //中音
0x22,0xfe,
0x56,0xfe,
0x85,0xfe,
0x9a,0xfe,
0xc1,0xfe,
0xe4,0xfe,
0x03,0xff, //高音
};
void delay(uint );
void ITimer0(void);//定时器初始化
void key(void);
void dtxs(int,int);
void song()
{
TH0=high;
TL0=low;
TR0=1;
delay(time*240);
}
void yinyue()
{
uchar code hls[]={ 5,2,2, 3,2,1, 5,2,1, 1,3,4, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 1,2,1, 2,2,1 ,3,2,2 ,2,2,1,
1,2,1 ,2,2,6, 5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2,
2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,6, 6,2,2, 1,3,2, 1,3,4, 7,2,2, 6,2,1, 7,2,1, 1,3,4 ,6,2,1,
7,2,1, 1,3,1 ,6,2,1, 6,2,1 ,5,2,1 ,3,2,1, 1,2,1, 2,2,6, 5,2,2, 3,2,1,
1,2,1, 1,3,3, 7,2,1, 6,2,2, 1,3,2, 5,2,4, 5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1, 1,2,6
};
uchar m;
n=0;
while(n<174)
{
m=hls[n]+7*(hls[n+1]-1)-1;
high=fre[m][1];
low=fre[m][0];
time=hls[n+2];
n=n+3;
song();
}
}
void main (void)
{
uchar num;
ITimer0();
speak=0;
while(1)
{
key();
switch(keyport)
{
case 0xfe:num=1;break;
case 0xfd:num=2;break;
case 0xfb:num= 3;break;
case 0xf7:num= 4;break;
case 0xef:num= 5;break;
case 0xdf:num= 6;break;
case 0xbf:num= 7;break;
case 0x7f:num= 8;break;
default:num= 0;break;
}
if(num==0)
{
TR0=0;
speak=0;
}
else
{
high=fre[7*yinjie+num-1][1];
low=fre[7*yinjie+num-1][0];
TR0=1;
}
dtxs(yinjie,num);
}
}
void ITimer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
void Timer0_isr(void) interrupt 1
{
TH0=high;
TL0=low;
speak=!speak;
if(zdbf==0)
{
delay(100);
if(zdbf==0)
{
bo++;
if(bo/2==1)
{ delay(100);
if(n<174)n=500; //n赋值大于174,跳出while,停止音乐
else n=0;
dtxs(3,0);
}
if(bo%2==0)
{ delay(100);
n=500; //n赋值大于174,跳出while,停止音乐
}
}
}/**/
}
void key()
{
if(zdbf==0)
{delay(100);
if(zdbf==0)
yinyue();
}
if(gao==0)
{
delay(100);
if(gao==0)
{
delay(100);
if(yinjie==2)
yinjie=1;
else yinjie=2;
}
}
if(di==0)
{
delay(100);
if(di==0)
{
delay(100);
if(yinjie==0)
yinjie=1;
else yinjie=0;
}
}
}
void delay(unsigned int x)
{
int a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void dtxs(k,l)//k是按键号,l是工作方式
{
char seg[14]={0x6f,0x0a,0xe3,0xcb,0x8e,0xcd,
0xed,0x0b,0xef,0xcf,0xaf,0xec,0x65,0xea};
P2=0x01;//选择第一个数码管
P0=seg[l];//显示按键号
delay(4);
P2=0x02;//选择第二个数码管
P0=seg[k+10];//显示工作方式
delay(4);
}
|