#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();
}
}
|