#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit a1=P2^2;
sbit a2=P2^3;
sbit a3=P2^4;//38译码管接口
sbit beep=P1^5;//蜂鸣器口
uchar num1,num2,num4,num5,num7,num8,tt,temp;
uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
212,212,106,126,159,169,190,119,119,126,159,142,159,0};//SONG_TONE 延时表决定了每个音符的频率
uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
9,3,12,12,12,12,12,9,3,12,12,12,24,0}; //播放各个音符,SONG_LONG 为拍子长度
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
void delay(uint z) //延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void DelayMStime(uint x)//蜂鸣器音乐延时函数
{
uchar t;
while(x--) for(t=0;t<120;t++);
}
void timer0() interrupt 1 //中断函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
}
void PlayMusic()//蜂鸣器音乐生日快乐
{
uint i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{ //播放各个音符,SONG_LONG 为拍子长度
for(j=0;j<SONG_LONG[i]*20;j++)
{
beep=~beep;
//SONG_TONE 延时表决定了每个音符的频率
for(k=0;k<SONG_TONE[i]/3;k++);
}
DelayMStime(10);
i++;
}
}
void keyscan()//键盘扫描函数
{
P1=0xfe;//扫描第一行列值
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xee : PlayMusic();
break;
case 0xde : num1++;//第一位数码管时间+1,后面类推
if(num1==3)
{num1=0;}
break;
case 0xbe : num2++;
if(num1==2)
{if(num2==4)
{num2=0;}
else if(num2==10)
{num2=0;}}
break;
case 0x7e : num2--;
if(num1==2)
{if(num2==0)
{num2=3;}
else if(num2==0)
{num2=9;}}
break;
}
while(temp!=0xf0)//检测按键是否按下
{ temp=P1;temp=temp&0xf0;}
}
P1=0xfd;//扫描第二行列值
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xed : num4++;
if(num4==6)
{num4=0;}
break;
case 0xdd : num4--;
if(num4==0)
{num4=5;}
break;
case 0xbd : num5++;
if(num5==10)
{num5=0;}
break;
case 0x7d : num5--;
if(num5==0)
{num5=9;}
break;
}
while(temp!=0xf0)//检测按键是否按下
{ temp=P1;temp=temp&0xf0;}
}
P1=0xfb;//扫描第三行列值
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xeb : num7++;
if(num7==6)
{num7=0;}
break;
case 0xdb : num7--;
if(num7==0)
{num7=5;}
break;
case 0xbb : num8++;
if(num8==10)
{num8=0;}
break;
case 0x7b : num8--;
if(num8==0)
{num8=9;}
break;
}
while(temp!=0xf0)//检测按键是否按下
{ temp=P1;temp=temp&0xf0;}
}
P1=0xf7;//扫描第四行列值
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(10);
temp=P1;
switch(temp)
{
case 0xe7 : num2=0;
break;
case 0xd7 : num4=0;
break;
case 0xb7 : num5=0;
break;
case 0x77 : num7=0;num8=0;
break;
}
while(temp!=0xf0) //检测按键是否按下
{ temp=P1;temp=temp&0xf0;}
}
}
void buzzer()//蜂鸣器12点响一下
{
if(num1==1)
{
if(num2==2)
{
if(num8==0)
{
beep=~beep;
delay(3);
}
}
}
}
void timer() //时钟,38译码管软件定时一位一位操作显示效果比较好
{
a1=1;
a2=1;
a3=1;//第1位数码管
if(num1==3)
{
num1=0;
}
keyscan();
P0=table[num1];
delay(3);
a1=0;
a2=1;
a3=1;//2
if(num1==2)
{
if(num2==4)
{
num1++;
num2=0;
}
}
else if(num2==10)
{
num1++;
num2=0;
}
P0=table[num2];
delay(3);
a1=1;
a2=0;
a3=1;//3
P0=0x40;
delay(3);
a1=0;
a2=0;
a3=1;//4
if(num4==6)
{
num2++;
num4=0;
}
P0=table[num4];
delay(3);
a1=1;
a2=1;
a3=0;//5
if(num5==10)
{
num4++;
num5=0;
}
P0=table[num5];
delay(3);
a1=0;
a2=1;
a3=0;
P0=0x40;
delay(3);
a1=1;
a2=0;
a3=0;
if(num7==6)
{
num5++;
num7=0;
}
P0=table[num7]; //7
delay(3);
if(tt==20) //间隔正1秒
{
a1=0;
a2=0;
a3=0; //第8个数码管
tt=0;
num8++;
if(num8==10)
{
num7++;
num8=0;
}
P0=table[num8];
}
delay(3); //延时数字3最为稳定
}
void main()
{
TMOD=0X01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;//开总中断
ET0=1;//开定时器中断
TR0=1;//启动定时器0
P0=0x3f;
while(1)
{
timer();
buzzer();
}
}
|