数字电子时钟的设计 - 图文 下载本文

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