If(fresh) /*判断是否要刷新显示(分或时变化)*/ {
buf[0]=hourh; /*是,则新的时间送到显示缓冲区*/ buf[1]=hourl; buf[2]=miunh; buf[3]=miunl;
display(); /*显示刷新*/
if(sec) /*判断秒指针要刷新否*/ {
sec =0 /*是,则刷新(闪烁)*/ L1=!L1; L2=!L2;
Dela20ms(); } }
else(sec) {
if(sec) {
sec=0; L1=!L1; L2=!L2; delay20ms(); } } } }
void display(void) {
uchar out;;
DISPCON=1; out=seg[buf[0]]; SBUF=out; while(!T1); T1=0;
out=seg[buf[1]]; out&=OXfe; SBUF=out; while(!T1); T1=0;
out=seg[buf[2]]; SBUF=out; while(!T1); T1=0;
out=seg[buf[3]]; SBUF=out; while(!T1); T1=0;
DISPCON=0; }
buf[0]=hourh; buf[1]=hourl; buf[2]=miunh; buf[3]=miunl; if(ss)
/*点亮时间不能太长,否则影响秒指针,短则太暗*/ /*关闭显示,防止传送数据期间闪烁*/ /*取出高位字段码*/ /*送入74LS164*/ /*等待发送完成*/ /*取出低位时段码*/ /*显示时分分隔符*/ /*分*/ /*所有数据已送入后开显示*/ /*将目前设定的参数送显示缓冲区*/ 18
{
swich(setflag) /*判当前设定位*/ {
case OX01; buf[0]=OX0b; /*全暗代码*/ break;
case OX02; buf[1]=OX0b; break;
case OX04; buf[2]=OX0b; break;
case OX08; buf[3]=OX0b; break; } }
display();
void timerl (void) interrupt 3 using 1 {
TH1=OX3c; /*100ms定时常数*/ TL1=OXb0;
count++; /*中断次数加1*/
if(count!=5) /*判到10次(1s)否,不到直接返回*/ return;
ss=!ss; /*ss闪烁标志求反*/ count=0; }
void settime(void) {
uchar i ;
while(S1); /*等待s1键开始设置*/ for(i=0;i<4;i++)
delay20ms(); /*延时去抖动*/ while(S1); setflag=0; ss=0;
hh=1; /*设置当前位标志*/ TR1=1; /*启动定时器T1*/ ET1=1; /*允许T1溢出中断*/ void settime(void) {
uchar i ;
while(S1); /*等待s1键开始设置*/ for(i=0;i<4;i++)
delay20ms(); /*延时去抖动*/ while(S1); setflag=0; ss=0;
hh=1; /*设置当前位标志*/ TR1=1; /*启动定时器T1*/ ET1=1; /*允许T1溢出中断*/ break;
case OX04; buf[2]=OX0b; break;
case OX08; buf[3]=OX0b; break; }
19
}
/******************************************************/ display();
if(S1) goto sett_1; if(ml) {
TR1=0; /*关闭定时器T1*/ ET1=0; /*禁止T1溢出中断*/ buf[0]=hourh;
buf[1]=hourl; buf[2]=minuh; buf[3]=minul;
#include return; /*如果当前编辑的份低位,则按S1键结束设定*/ }
setflag<<=1; /*当前位右移(标志左移1位)*/ continue;
sett_1: if(S2) continue; for(i=0;i<4;i++)
delay20ms(); /*延时去抖动*/ if(S2) continue; if(!hh) goto sett-2; {
hourl++; /*时高位加1处理*/ if(hourh!=2) continue;
hourh=0; /*时高位只能是0,1*/
continue;
}
sett_2: if(!h1) goto sett-3; {
hourl++;/*时低位加一处理,高位为0,可以
是0^9,否则,只能0^2*/
if(hour) goto sett-20; if(hourl==10) goto sett-21; continue;
sett-21: hourl=10; continue;
sett-20: if(hourl==3) goto sett-22; continue; sett-22: hourl=0; continue; }
sett_3: if(!mh) goto sett-4;
{ miunh++; /*分高位加1处理,只能是0^5*/ if(miunh==6) goto sett-30; continue;
sett-30: miunh=0; continue; }
sett_4: minul++; /*分低位加1处理,只能是0^9*/ if(minul==10) goto sett-40; continue;
sett-40: minul=0; continue; } }
“REG51.H”
20
#define uchar unsigned char
#define PSEG OX30 /*P.的段码*/
/*0^9和P,暗的的端码(共阳数码管) */ uchar code
seg[]={OX03,OX9F,OX25,OX0D,OX99,OX49,OX41,OX1F,OX01,OX09,OX30,OXff}; /******************************************************/
;74LS164的3 4 5 6 10 11 12 13对应数码管的A,B,C,D,E,F,G,DP,DB
OCoh,OF9H,OA4H,OB0H,99H; DB 92H,82H,OF8H,80H,90H
/******************************************************/ /*输入输出定义*/
sbit DISPCON=P3^2; /* 显示控制*/ sbit S1 = P1^3; /* 设置键*/ sbit S1= P1^2; /* 数字+1键*/
sbit L1= P1^7; /* L1,L2构成秒指针*/ sbit L2= P1^6;
/* 全局变量定义 */
uchar buf[4]; /* 显示缓冲区*/ uchar hourh; /* BCD时钟各位*/ uchar hourl; uchar minuh; uchar minul;
uchar second; /* 秒变量*/
uchar count; /* 溢出中断计数器*/ uchar bdata setflag; /* 设置用标志字节*/ uchar bdata uflag; /* 通用标志字节*/ /* 位变量定义*/
/* 以下4个位变量在setflag中,便于移位处理*/
sbit hh=setflag^0; /* 当前设置位标志*/ sbit h1=setflag^1; bit mh=setflag^2; bit m1=setflag^3; /* 以下变量在uflag*/
sbit fresh=uflag^0; /* 显示刷新标志*/ sbit ss=uflag^1; /* 位闪烁标志*/ sbit sec=uflag^2; /* 秒指针标志*/ sbit warning=uflag^3; /* 定时标志*/
/*------------------------------------------------------------------------------*/ sbit tfix=uflag^4; /* 开始修正标志*/
#define N 60 /* 误差值,单位:1/10秒,默认为0,即不修正*/ /*------------------------------------------------------------------------------*/ /*函数说明*/
void sys-init(void); void t0-init(void); void uart-init(void); void display(void); void delay20ms(void); void settime(void);
void t1-init(void);
/******************************************************/ ;时钟主函数:main()
;定时器T0工作与中断方式
;一旦走时开始,无法进行设置。如果重新设置,则必须复位
21