89c51单片机数码管时钟例程.docx
《89c51单片机数码管时钟例程.docx》由会员分享,可在线阅读,更多相关《89c51单片机数码管时钟例程.docx(14页珍藏版)》请在冰豆网上搜索。
89c51单片机数码管时钟例程
//data:
2010-07-06
//writer:
wuxiandian
//fame:
wannianli
//function:
a时分秒的精确显示及设定;b定时的精确显示及设定;c定时时刻不影响时钟精确走时;
//d当输入数值有误将蜂鸣报警且数值归1或0;e可以进行定时时间的查看;
//f可进行星期的设定及查看g可进行年月日的设定及查看
//h可进行平、闰年的分辨;i拥有定时时间到报时1分及整点提示,显示不会闪烁;
//j定时、调时为移位显示,设定万年历为单显;星期、定时、调时、年、月日分屏显示;
//k可进行数码管和蜂鸣器的检验;L当闹钟响起可随时关闭;
#include
voidcontrol(void);//判断是否进行键盘操作;
voiddisplay(char,char);//显示,位控和段控;
voiddelayms(unsignedintx);//延时;
voidcommon(void);//定时、调时显示控制;
voidfixed_times(void);//定时,进行时分秒输入。
先按11号键,再按六位数字键,自动返回运行;
voidswap_times(void);//调时,进行时分秒输入。
先按12号键,再按六位数字键,自动返回运行;
voidfixed_show(void);//全显示,检查数码管和蜂鸣器好坏,按零号键;
voidweek(void);//星期设定8返回7;
voidweek_show(void);//星期显示6返回5;
voidcalendar_show(void);//日历显示4显示年,3显示月日,2返回;
voidcalendar(void);//日历设定2显示年,3显示月日,4返回;
charkey(void);//键盘;
voidinitial(void);//初始化;定时中断
charhour1=1,hour0=2,min1=0,min0=0,sec1=0,sec0=0,n=0,w=1,v=1,//主显示全局变量;n循环次数w星期显示v闹铃判断位;
fhour1=0,fhour0=0,fmin1=0,fmin0=0,fsec1=0,fsec0=0,//定时、调时共用全局变量;
t6=0,t5=6,t4=0,t3=0,t2=0,t1=0,//定时显示全局变量;
year3=2,year2=0,year1=1,year0=0,mouts1=0,mouts0=7,day1=0,day0=7;//年月日全局变量;
inta1[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年;
inta0[12]={31,29,31,30,31,30,31,31,30,31,30,31};//闰年;
int*p;//为a1.a0设置指针;
//********************************************************************定义和声明;
voidmain(void)
{
initial();//初始化
while
(1)
{
P1=0x0f;
if(P1!
=0x0f)//判位进入调控程序;
control();
P1=0xff;
display(5,hour1);///主显示程序;
delayms(150);
display(4,hour0);
delayms(150);
display(3,min1);
delayms(150);
display(2,min0);
delayms(150);
display(1,sec1);
delayms(150);
display(0,sec0);
delayms(150);
}
}
//*************************************************判位操作显示;
voidcontrol(void)
{
P1=0xbf;
if(P1==0xbe)//1显示数码管和蜂鸣器,自动返回;
{P2=0x00;P0=0xff;
delayms(2000);}
elseif(P1==0xb7)//4显示某年,3显示某月日,2返回;
calendar_show();
elseif(P1==0xbb)//3定时年,2定时月日,1返回;
calendar();
P1=0xef;
if(P1==0xeb)//11定时,自动返回;
fixed_times();
elseif(P1==0xe7)//12调时,自动返回;
swap_times();
elseif(P1==0xed)//10显示定时9返回;
fixed_show();
P1=0xdf;
if(P1==0xd7)//8星期设置7返回;
week();
elseif(P1==0xdd)//6星期显示5返回;
week_show();
elseif(P1==0xde)//关闭闹铃;
v=1;
}
//******************************************************中断入口;
voidtime0(void)interrupt1//定时中断0;
{unsignedintq;
if(v==0)//盘闹铃是否工作;
P2_7=0;
else
P2_7=1;
q=year3*1000+year2*100+year1*10+year0;//平、闰年判别;
if((q%4==0&&q%100!
=0)||(q%400==0))
p=a0;//闰年指针指向;
elsep=a1;//平年指针指向;
TH0=0xb8;//20ms定时;
TL0=0x00;
n==50?
n=0:
++n;//循环次数;
if(n==0)//时分秒的进位;
{++sec0;
if(sec0==10)
{sec0=0;
++sec1;
if(sec1==6)
{sec1=0;
++min0;
if(hour1==t6&&hour0==t5&&min1==t4&&min0==t3)//判蜂鸣器响,
v=0;//闹铃标志位;
else//判蜂鸣器,虽然雍杂,但蜂鸣时数码管不闪烁;
v=1;
if(min0==10)
{min0=0;
++min1;
if(min1==6)
{min1=0;
++hour0;
P2_7=0;
delayms(8000);
if(hour0==10)
{hour0=0;
++hour1;
}
}
}
}
}
}
if((hour1==2)&&(hour0==4))//判是否大于24点
{hour1=0;
hour0=0;
++w;
if(w>7||w<1)//星期控制1-7天;
w=1;
if(++day0==10)//日的判断进位;
{day0=0;
++day1;}
if(day1*10+day0>*(p+(mouts1*10+mouts0-1)))
{day0=1;
day1=0;
++mouts0;}
if(mouts0==10)//月的判断进位;
{mouts0=0;
++mouts1;}
if(mouts1*10+mouts0>12)
{mouts0=1;
mouts1=0;
++year0;}
if(year0==10)//年的判断进位;
{year0=0;
++year1;
if(year1==10)
{year1=0;
++year2;
if(year2==10)
{year2=0;
++year3;
if(year3==10)
{year3=0;}
}
}
}
}
}
////*****************************************************************显示程序;
voiddisplay(charm,charn)
{
unsignedchary[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsignedcharz[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
P2=z[m];
P0=y[n];
}
///*********************************************************************延时程序;
voiddelayms(unsignedintx)
{
unsignedinty;
for(y=0;y}
////****************************************************************键盘程序;
charkey(void)
{
P1=0x0f;
loop:
if(P1==0x0f)
gotoloop;
delayms(3350);
if(P1==0x0f)
gotoloop;
while
(1)
{P1=0xbf;
if(P1_0==0){while(P1!
=0xbf);return0;}
if(P1_1==0){while(P1!
=0xbf);return1;}
if(P1_2==0){while(P1!
=0xbf);return2;}
if(P1_3==0){while(P1!
=0xbf);return3;}
P1=0xdf;
if(P1_0==0){while(P1!
=0xdf);return4;}
if(P1_1==0){while(P1!
=0xdf);return5;}
if(P1_2==0){while(P1!
=0xdf);return6;}
if(P1_3==0){while(P1!
=0xdf);return7;}
P1=0xef;
if(P1_0==0){while(P1!
=0xef);return8;}
if(P1_1==0){while(P1!
=0xef);return9;}
}
}
//*************************************************************定时时间程序;
voidfixed_times(void)
{
P2=0xfe;
P0=0x71;
common();
t6=fhour1;
t5=fhour0;
t4=fmin1;
t3=fmin0;
t2=fsec1;
t1=fsec0;
}
///************************************************************调时程序;
voidswap_times(void)
{
P2=0xfe;
P0=0x6d;
common();
hour1=fhour1;
hour0=fhour0;
min1=fmin1;
min0=fmin0;
sec1=fsec1;
sec0=fsec0;
}
//************************************************************初始化程序;
voidinitial(void)
{
TH0=0xb8;
TL0=0x00;
IE=0x82;
TMOD=0x01;
TR0=1;
}
//*******************************************调时、定时共用设定和显示程序;
voidcommon(void)
{
charf=0,j=0,k;
for(k=0;k<6;++k)
{
switch(++f)
{
case1:
{for(fsec0=key();fsec0>2;fsec0=0)
{P2_7=0;
delayms(3000);}
P2_7=1;break;}
case2:
{fsec1=fsec0;
for(fsec0=key();fsec1>=2&&fsec0>=4;fsec0=0)
{P2_7=0;
delayms(3000);}
P2_7=1;break;}
case3:
{fmin0=fsec1;
fsec1=fsec0;
for(fsec0=key();fsec0>5;fsec0=0)
{P2_7=0;
delayms(3000);}
P2_7=1;break;}
case4:
{fmin1=fmin0;
fmin0=fsec1;
fsec1=fsec0;
fsec0=key();break;}
case5:
{fhour0=fmin1;
fmin1=fmin0;
fmin0=fsec1;
fsec1=fsec0;
for(fsec0=key();fsec0>5;fsec0=0)
{P2_7=0;
delayms(3000);}
P2_7=1;break;}
case6:
{fhour1=fhour0;
fhour0=fmin1;
fmin1=fmin0;
fmin0=fsec1;
fsec1=fsec0;
fsec0=key();break;}
}
for(P1=0x0f;(P1==0x0f)&&(f<=6);j=0)
{
if(++j<=f)
{display(0,fsec0);
delayms(200);
if(++j<=f)
{display(1,fsec1);
delayms(200);
if(++j<=f)
{display(2,fmin0);
delayms(200);
if(++j<=f)
{display(3,fmin1);
delayms(200);
if(++j<=f)
{display(4,fhour0);
delayms(200);
if(++j<=f)
{display(5,fhour1);
delayms(200);}
}
}
}
}
}
}
}
}
///********************************************************定时显示程序;
voidfixed_show(void)
{
do{
P1=0xef;
display(5,t6);
delayms(150);
display(4,t5);
delayms(150);
display(3,t4);
delayms(150);
display(2,t3);
delayms(150);
display(1,t2);
delayms(150);
display(0,t1);
delayms(150);
}
while(P1!
=0xee);
}
//*****************************************星期设定程序;
voidweek(void)
{
delayms(5000);
for(w=key();w>7||w<1;w=1);
P1=0xdf;
do
display(5,w);
while(P1!
=0xdb);
P1=0xff;
}
//******************************************星期显示程序;
voidweek_show(void)
{
P1=0xdf;
do
display(5,w);
while(P1!
=0xde);
P1=0xff;
}
///*****************************************万年历显示程序;
voidcalendar_show(void)
{
do
{
display(4,year3);//年显示;
delayms(150);
display(3,year2);
delayms(150);
display(1,year1);
delayms(150);
display(0,year0);
delayms(150);}
while(P1!
=0xbb);
do
{
display(4,mouts1);//月日显示;
delayms(150);
display(3,mouts0);
delayms(150);
display(1,day1);
delayms(150);
display(0,day0);
delayms(150);}
while(P1!
=0xbd);
P1=0xff;
}
//*******************************************万年历设定程序;
voidcalendar(void)
{
P2=0xfe;
P0=0x6e;
do{}
while(P1==0xbb);
display(4,year3=key());//年设定;
display(3,year2=key());
display(1,year1=key());
display(0,year0=key());
do{P1=0xbf;}
while(P1!
=0xbd);
P2=0xfe;
P0=0x63;
do{}
while(P1==0xbd);//月日设定;
display(4,mouts1=key());
display(3,mouts0=key());
if(mouts1*10+mouts0>12||mouts1*10+mouts0<1)
{mouts1=0;mouts0=1;P2_7=0;delayms(1200);}
P2_7=1;
display(1,day1=key());
display(0,day0=key());
if(day1*10+day0>*p||day1*10+day0<1)
{day1=0;day0=1;P2_7=0;delayms(1200);}
P2_7=1;
do{P1=0xbf;}
while(P1!
=0xbe);
P1=0xff;
}