#include<reg51.h> sbit p1_0=P1^0; sbit p1_1=P1^1; sbit
p1_2=P1^2; sbit p1_3=P1^3; sbit p1_4=P1^4; sbit
p3_2=P3^2; unsigned char code zimal[13]=
{0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,
0x40,0x80,0x00,}; /*共阴极字形代码,显示0-9字形码,最
后三个代码分别表示‘-’,‘.’‘熄灭’*/ unsigned int
year,month,day,hour,minute,second;//定义变量年,月,日,时
,分,秒; void delay(); //延时函数; void xianshi
(unsigned int h,min,s); //显示时间函数; void
ymdxianshi(unsigned int year,month,day); //显示年月日
; void fengming(); //蜂鸣器
函数; int leap(unsigned int year); //判
断闰年函数; unsigned int h,m,s=5; //记录定时
时间; unsigned int mode=1,td=0,yw=0; //状态; void
main() { year=2010;month=5;day=20;hour=23;minute=59;
second=0; /*初始化年,月,日,时,分,秒*/ TMOD=0x10;
//定时器1;模式1; TL1=0xb0;TH1=0x3c;定时时间为50ms
TR1=1;//打开定时器1 ET1=1;//定时器1溢出中断允许位
EX0=1;//外部中断0允许 IT0=1;//外部中断0触发方式为边
沿触发 EA=1; while(1) //主循环; { if
(hour==h&&minute==m&&second==s) fengming(); //定时时间
到,蜂鸣器响; if(mode%2==0) ymdxianshi
(year,month,day); //显示年月日 else {if(td%3==2)
xianshi(h,m,s); // 定时状态; else
xianshi(hour,minute,second); //正常显示时间状态;
} } } void delay() //延时
函数;{ unsigned int i; for(i=0;i<400;i++); } void
ymdxianshi(unsigned int year,month,day) //年月日的显示
与调整 {int i,j; i++; if(td%2==1&&yw%8==0&&i%2==0) //
点亮年的第一个 { P2=0x7f; P0=zimal[12];
for(j=0;j<2000;j++); } else { P2=0x7f;
P0=zimal[year/1000]; delay(); } if(td%2==1&&yw%
8==1&&i%2==0) //点亮年的第二个 { P2=0xbf;
P0=zimal[12]; for(j=0;j<1800;j++); } else {
P2=0xbf; P0=zimal[year%1000/100];delay(); } if
(td%2==1&&yw%8==2&&i%2==0)//点亮年的第三个 {
P2=0xdf; P0=zimal[12]; for(j=0;j<1800;j++); }
else { P2=0xdf; P0=zimal[year%100/10];
delay(); } if(td%2==1&&yw%8==3&&i%2==0) //点亮年的
第四个{ P2=0xef; P0=zimal[12]; for
(j=0;j<1800;j++); } else //显示年 { P2=0xef;
P0=zimal[year%10]; delay(); } if(td%2==1&&yw%
8==4&&i%2==0)//显示月点亮 { P2=0xf7;
P0=zimal[12];P2=0xfb; P0=zimal[12]; for
(j=0;j<1800;j++); } else { P2=0xf7;
P0=zimal[month/10]; delay(); P2=0xfb; P0=zimal
[month%10]; delay(); }P2=0xef;//显示点
P0=zimal[11]; for(j=0;j<100;j++); P2=0xfb;
P0=zimal[11]; for(j=0;j<100;j++); if(td%2==1&&yw%
8==5&&i%2==0)//显示日的第一个 { P2=0xfd;
P0=zimal[12]; for(j=0;j<1800;j++); } else {
P2=0xfd; P0=zimal[day/10]; delay();} if(td%
2==1&&yw%8==6&&i%2==0)//显示日的第二个 { P2=0xfe;
P0=zimal[12]; for(j=0;j<1800;j++); } else {
P2=0xfe; P0=zimal[day%10]; delay(); } } void
xianshi(unsigned int h,min,s) //显示时间函数;{
unsigned int i,j; i++; if(td%3!=0&&yw%
6==0&&i%2==0) { P2=0x7f; //显示时的第一个;
P0=zimal[12]; for(j=0;j<2000;j++); } else {
P2=0x7f; P0=zimal[h/10]; delay(); }
if(td%3!=0&&yw%6==1&&i%2==0)//显示时的第二个 {
P2=0xbf; P0=zimal[12];for(j=0;j<2000;j++); }
else { P2=0xbf; P0=zimal[h%10]; delay();
} //显示- P2=0xdf; P0=zimal[10];
delay(); if(td%3!=0&&yw%6==2&&i%2==0) //显示分的第
一个; { P2=0xef; P0=zimal[12]; for
(j=0;j<2000;j++); } else {
P2=0xef; //显示分的第二个; P0=zimal[min/10];
delay(); } if(td%3!=0&&yw%6==3&&i%2==0) {
P2=0xf7; P0=zimal[12]; for(j=0;j<2000;j++);
} else{ P2=0xf7; P0=zimal[min%10]; delay
(); } P2=0xfb; //显示- P0=zimal[10];
delay(); if(td%3!=0&&yw%6==4&&i%2==0) //显示秒的
第一个; { P2=0xfd; P0=zimal[12]; for
(j=0;j<2000;j++); } else { P2=0xfd;
P0=zimal[s/10]; delay(); }if(td%3!=0&&yw%
6==5&&i%2==0) //显示秒的第二个 { P2=0xfe;
P0=zimal[12]; for(j=0;j<2000;j++); } else
{P2=0xfe; P0=zimal[s%10]; delay(); } }
void ex0()interrupt 0 //外部中断零; { unsigned int i;
if(p1_3==0)delay(); if(p1_3==0) {mode++;td=0;} if
(p1_1==0)delay(); if(p1_1==0)yw++; //移位; if
(p1_0==0)delay(); if(p1_0==0)td++; //修改调整时
间状态; if(mode%2==0) //调整日期; { if(td%
2==1) for(i=0;i<10;i++); if(p1_2==0)delay();
if(p1_2==0) //移位; { if(yw%8==0)year+=1000;
//调整对应位的数值; if(yw%8==1){year+=100;if
(year%100/10==0)year-=1000;} if(yw%8==2)
{year+=10;if(year/10%10==0)year-=100;} if(yw%
8==3) {year++;if(year%10==0)year-=10;} if(yw%
8==4)month++; if(yw%8==6){day++;if(day%
10==0)day-=10;} if(yw%8==5) day+=10;
} // if(year>=2500)year=0; //年份小于2500;
if(month>12)month=1; //月份小于12; switch(month)
//日期限制 { case 4: case 6:
case 9: case 11:if(day>30)
day=1;break;//4,6,9,11月30天;case 2 : {if
(leap(year)) //闰年2月29天; while
(day>29)day=1; else
while(day>28)day=1;//非闰年28天;}break;
default:if(day>31)day=1; //1,3,5,7,8,10,12月31天; }
} } //else if(td%3==1) //调整时间; else if
(td%3==1) { ET1=0; //时钟中断 for (i=0;i<10;i++);
if(p1_2==0)delay(); if(p1_2==0) { if(yw%
6==1){hour++;if(hour%10==0) hour-=10;} if(yw%6==0)
hour+=10; if(yw%6==3){minute++;if(minute%10==0)
minute-=10;} if(yw%6==2)minute+=10; if(yw%6==5)
{second++; if(second%10==0)second-=10;}if(yw%6==4)
second+=10; } if(hour>23)hour=0; if(minute>59)
minute=0; if(second>59)second=0; } else //定时状
态; { ET1=1; if(td%3==2) { for
(i=0;i<10;i++); if(p1_2==0) //定时; {
if(yw%6==1){h++;if(h%10==0) h-=10; } if(yw%
6==0)h+=10; if(yw%6==3){m++;if(m%10==0)m-=10;}
if(yw%6==2)m+=10; if(yw%6==5){s++; if(s%10==0)
s-=10;}if(yw%6==4)s+=10; } if(h>23)h=0;
if(m>59)m=0; if(s>59)s=0; }} } void
time1()interrupt 3 //定时器1中断; { unsigned char i;
TF0=0; TL0=0xb0; TH0=0x3c; i++; if(i==20) //1秒钟
到; { second++; i=0; } if(second==60)//1分
钟; { second=0; minute++; }if(minute==60)//1小
时; { minute=0; hour++; } if(hour==24) //1天;
{ hour=0; day++; } switch(month) //1
月; { case 4: case 6: case 9: case
11:if(day>30){month++;day=1;}break;//4,6,9,11月30天;
case 2:{if(leap(year)) if(day>29)
{month++;day=1;} //闰年29天; else if(day>28)
{month++;day=1;}//非半闰年28天; }break;
default:if(day>31){month++;day=1;}//1,3,5,7,8,10,12月30
天; if(month>12) //1年; {year++; month=1;
} } } void fengming() //蜂鸣器; { int m,n; for
(m=0;m<=100;m++) {p1_4=!p1_4; for(n=0;n<380;n++); } }
int leap(unsigned int year) //判断闰年函数; { int
leap; if(year%4==0&&year%100!=0||(year%400==0))
leap=1; else leap=0;return(leap); }