#include
#define uchar unsigned char
#define uint unsigned int
sbit key1 = P3^2; //手动控制数码管1,2位
sbit key2 = P3^3; //手动控制数码管4,5位
sbit key3 = P3^4; //手动控制数码管7,8位
sbit key5 = P1^6; //手动切换数码管显示(可显示三种情况:时钟,日期,闹钟时间)
sbit key6 = P1^7; //停止闹钟音乐
sbit alarm = P1^4; //闹钟
uchar count,hour,minute,second; // 时钟时间 时分秒
uchar i;
uchar h,s,m; //闹钟时间 时分秒
uchar pattern=0; //工作模式 (0:时钟模式 1;日期模式 2:闹钟模式)
uint year,month,day; //日期时间 年月日
uchar code led[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码
uchar num;
uchar code SONG[] ={ //祝你平安
0x26,0x20,0x20,0x20,0x20,0x20,0x26,0x10,0x20,0x10,0x20,0x80,0x26,0x20,0x30,0x20,
0x30,0x20,0x39,0x10,0x30,0x10,0x30,0x80,0x26,0x20,0x20,0x20,0x20,0x20,0x1c,0x20,
0x20,0x80,0x2b,0x20,0x26,0x20,0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x80,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x60,0x40,0x10,0x39,0x10,0x26,0x20,
0x30,0x20,0x30,0x20,0x39,0x10,0x26,0x10,0x26,0x80,0x26,0x20,0x2b,0x10,0x2b,0x10,
0x2b,0x20,0x30,0x10,0x39,0x10,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x20,
0x20,0x10,0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x18,0x20,0x18,0x20,0x26,0x20,
0x20,0x20,0x20,0x40,0x26,0x20,0x2b,0x20,0x30,0x20,0x30,0x20,0x1c,0x20,0x20,0x20,
0x20,0x80,0x1c,0x20,0x1c,0x20,0x1c,0x20,0x30,0x20,0x30,0x60,0x39,0x10,0x30,0x10,
0x20,0x20,0x2b,0x10,0x26,0x10,0x2b,0x10,0x26,0x10,0x26,0x10,0x2b,0x10,0x2b,0x80,
0x18,0x20,0x18,0x20,0x26,0x20,0x20,0x20,0x20,0x60,0x26,0x10,0x2b,0x20,0x30,0x20,
0x30,0x20,0x1c,0x20,0x20,0x20,0x20,0x80,0x26,0x20,0x30,0x10,0x30,0x10,0x30,0x20,
0x39,0x20,0x26,0x10,0x2b,0x10,0x2b,0x20,0x2b,0x40,0x40,0x10,0x40,0x10,0x20,0x10,
0x20,0x10,0x2b,0x10,0x26,0x30,0x30,0x80,0x00};
/*定时器1中断:用于闹钟音乐播放*/
void Time0_Int() interrupt 3
{
TH1= 0xD8;
TL1= 0xEF; //计入初值,10毫秒定时
num++; //长度加1
}
/*功能:1MS延时子程序*/
void Delay_xMs(uint x) //音乐播放所需延时
{
unsigned int i,j;
for( i =0;i < x;i++ )
{
for( j =0;j<3;j++ );
}
}
/* 延时子程序:时钟显示所需*/
void delay(uint time) //延时
{
uchar j=5;
for(; time>0 ; time--)
for(;j>0;j--);
}
void wait(uchar n) //延时
{
for(i=0 ; i delay(100);
}
/*功能:闹钟歌曲播放子程序*/
void Play_Song()
{
unsigned char Temp1,Temp2;
unsigned int Addr;
num = 0; //中断计数器清0
Addr = 0; //SONG下标
while(1)
{
Temp1 = SONG[Addr++];
if(key6!=1) //判断key6键按下
{
delay(100); //硬件防抖
if(key6!=1)
{
Temp1=0x00;
}
}
if ( Temp1 == 0x00 ) //歌曲结束符
{
return;
}
else
{
Temp2 = SONG[Addr++];
TR1 = 1;
while(1)
{
alarm= ~alarm;
Delay_xMs(Temp1);
if ( Temp2 == num )
{
num = 0;
break;
}
}
}
}
}
void INT_T() interrupt 1 //中断子程序,时间,日期自动进位
{
TH0=0x3c;
TL0=0xb0;
count++;
if(count==20)
{
count=0;
second++; //秒自增
if(second==60)
{
second=0;
minute++; //分自增
if(minute==60)
{
minute=0;
hour++; // 时自增
if(hour==24)
{
hour=0;
day++; // 日自增
if(((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==32)||
((month==4||month==6||month==9||month==11)&&day==31)||
((month==2&&(year%400==0||(year%100!=0&&year%4==0)))&&day==30)||
((month==2&&year%4!=0)&&day==29) )
{
day=1;
month++;
if(month==13)
{
month=1;
year++;
if(year==100)
year=0;
}
}
}
}
}
}
}
void main() //主函数
{
TMOD=0X11; //定时器1方式1;定时器0方式1
TH0=0x3c;
TL0=0xb0; //计入初值,定时50毫秒
EA=1; //总中断允许
ET0=1; //定时器中断允许
ET1=1;
TR0=1; //允许计数
hour=0;
minute=0;
second=0; //时钟初值
year=2017;
month=12;
day=12; //日期初值
h=8;
m=0;
s=0; //闹钟初值
while(1)
{
alarm=0; //闹钟关闭
if(pattern==0) //pattern=0,时钟显示
{
P2=0x7f;
P0=led[hour/10];
wait(1);
P2=0xbf;
P0=led[hour%10];
wait(1);
P2=0xdf;
P0=0x40;
wait(1);
P2=0xef;
P0=led[minute/10];
wait(1);
P2=0xf7;
P0=led[minute%10];
wait(1);
P2=0xfb;
P0=0x40;
wait(1);
P2=0xfd;
P0=led[second/10];
wait(1);
P2=0xfe;
P0=led[second%10];
wait(1); //各位赋值
if(key1!=1) //按键1,时+1
{
delay(100); //硬件防抖
if(key1!=1)
hour++;
delay(100);
while(key1==0);
}
if(key2!=1) //按键2,分+1
{
delay(100);
if(key2!=1)
minute++;
delay(100);
while(key2==0);
}
if(key3!=1) //按键3,秒+1
{
delay(100);
if(key3!=1)
second++;
delay(100);
while(key3==0);
}
if(key5!=1) //按键5,切换工作模式
{
delay(100);
if(key5!=1)
pattern++;
if(pattern==3)
pattern=0;
delay(100);
while(key5==0);
}
}
if (hour==h && minute==m && second==s) //到达闹钟时间点
{
Play_Song();
}
if(pattern==1) //pattern=1,日期显示
{
P2=0x7f;
P0=led[year/1000];
wait(1);
P2=0xbf;
P0=led[year%1000/100];
wait(1);
P2=0xdf;
P0=led[year%100/10];
wait(1);
P2=0xef;
P0=led[year%10];
wait(1);
P2=0xf7;
P0=led[month/10];
wait(1);
P2=0xfb;
P0=led[month%10];
wait(1);
P2=0xfd;
P0=led[day/10];
wait(1);
P2=0xfe;
P0=led[day%10];
wait(1);
if(key1!=1) //年+1
{
delay(100);
if(key1!=1)
year++;
delay(100);
while(key1==0);
}
if(key2!=1) //月+1
{
delay(100);
if(key2!=1)
month++;
delay(100);
while(key2==0);
}
if(key3!=1) //日+1
{
delay(100);
if(key3!=1)
day++;
delay(100);
while(key3==0);
}
if(key5!=1) //切换工作模式
{
delay(100);
if(key5!=1)
pattern++;
if(pattern==3)
pattern=0;
delay(100);
while(key5==0);
}
if (hour==h && minute==m && second==s)
{
Play_Song();
}
}
if(pattern==2) //pattern=2,闹钟显示
{
P2=0x7f;
P0=led[h/10];
wait(1);
P2=0xbf;
P0=led[h%10];
wait(1);
P2=0xdf;
P0=0x40;
wait(1);
P2=0xef;
P0=led[m/10];
wait(1);
P2=0xf7;
P0=led[m%10];
wait(1);
P2=0xfb;
P0=0x40;
wait(1);
P2=0xfd;
P0=led[s/10];
wait(1);
P2=0xfe;
P0=led[s%10];
wait(1);
if(key1!=1) //小时+1
{
delay(100); //进位规则 时
if(key1!=1)
h++;
if(h==24)
h=0;
delay(100);
while(key1==0);
}
if(key2!=1)
{ //分
delay(100);
if(key2!=1)
m++;
if(m==60)
{
m=0;
h++;
}
delay(100);
while(key2==0);
}
if(key3!=1) //秒
{
delay(100);
if(key3!=1)
s++;
if(s==60)
{
s=0;
m++;
}
delay(100);
while(key3==0);
}
if (hour==h && minute==m && second==s)
{
Play_Song();
}
if(key5!=1) //切换
{
delay(100);
if(key5!=1)
pattern++;
if(pattern==3)
pattern=0;
delay(100);
while(key5==0);
}
}
if(hour==24) hour=0; //手动更改时间时期时进位规则
if(minute==60)
{
hour++;
minute=0;
}
if(second==60)
{
minute++;
second=0;
}
if(year==100) year=0;
if(month==13)
{
year++;
month=1;
}
if(((month==1||month==3||month==5||month==7||month==8||month==10||month==12)&&day==32)||
((month==4||month==6||month==9||month==11)&&day==31)||
((month==2&&(year%400==0||(year%100!=0&&year%4==0)))&&day==30)||
((month==2&&year%4!=0)&&day==29))
{
day=1;
month++;
}
}
}