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