可以当作电子时钟用,功能不太完善,还有日历显示
改天改进改进再发过来,电路图改天吧
/****************************************************************************************
带有两次定时的日历时钟程序
mpu=at89c2051
p3_4 设置键
p3_5 调整键
四位数码共阳管显示
2004年-2099年
作者:bg4rff 刘兢兢
时间:2004年4月1日
****************************************************************************************/
#include <at89x51.h> /*包含器件配置文件*/
#define uchar unsigned char
#define uint unsigned int
uchar code data_7seg[10]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,};/*0~9的数码管段码*/
uchar code monthday[]={32,29,32,31,32,31,32,32,31,32,31,32};/*非闰年每月的天数加一天*/
uchar hour=0,min=0,sec=0,year=4; /*时、分、秒、年单元清零*/
uchar month=4,day=4; /*月、日单元赋初值,2004年4月4日*/
uchar deda=0; /*5ms计数单元清零*/
uchar t_hour1=0,t_min1=0; /*定时起时、分单元清零*/
uchar t_hour2=0,t_min2=0; /*定时止时、分单元清零*/
bit d_05s=0; /*0.5秒标志*/
uchar hlout=0xff; /*控制输出值标志*/
uchar set=0; /*模式设定标志*/
uchar m=0;
uchar flag=0; /*ram掉电标志*/
void delay(uint k); /*延时子函数*/
void conv(); /*走时单元转换*/
void p_out(); /*定时时间到输出子函数*/
void dirve(); /*走时时间输出驱动子函数*/
void dirvemd(); /*日历之月、日输出驱动子函数*/
void dirvey(); /*日历之年输出驱动子函数*/
void t_dirve1(); /*闹时起时间输出驱动子函数*/
void t_dirve2(); /*闹时止时间输出驱动子函数*/
/*走时函数*/
void time()
{
conv(); /*走时单元转换*/
dirve(); /*走时时间输出驱动子函数*/
p_out(); /*判别定时到否子函数*/
}
/*定时器t0 5ms初始化*/
void init_timer()
{
tmod=0x01;
th0=0xec;
tl0=0x82;
ie=0x82;
tr0=1;
}
/*扫描按键子函数*/
void scan_key()
{
delay(1);
if(p3_4==0)set++;
if(set>=10)set=0;
if(set==1)flag=0x55;
while(p3_4==0); /*按键未释放,在此等候*/
}
/*延时子函数*/
void delay(uint k)
{
uint i,j;
for(i=0;i<k;i++){
for(j=0;j<121;j++)
{;}}
}
/*5ms定时中断服务子函数*/
void zd(void) interrupt 1
{
th0=0xec;
tl0=0x82;
deda++;
}
/*算出某年某月有多少天*/
uchar month_n_day(uint y,uchar m)
{ if(m==2)
return(((y%4==0)&&(y%100!=0)||(y%400==0))?29:28);
else
return(monthday[m-1]);
}
/*走时时间输出驱动子函数*/
void dirve()
{
p1=data_7seg[hour/10];p3=hlout&0xf7;delay(1);
p1=data_7seg[hour%10];p3=hlout&0xfb;delay(1);
if(d_05s==1){if(p3_2==0)p1_7=0;else p1_7=1;}
delay(1);
p1=data_7seg[min/10];p3=hlout&0xfd;delay(1);
p1=data_7seg[min%10];p3=hlout&0xfe;delay(1);
}
/*走时年输出驱动子函数*/
void dirveym()
{
p1=0xa4;p3=hlout&0xf7;delay(1);
p1=0xc0;p3=hlout&0xfb;delay(1);
p1=data_7seg[year/10];p3=hlout&0xfd;delay(1);
p1=data_7seg[year%10];p3=hlout&0xfe;delay(1);
}
/*走时月、日输出驱动子函数*/
void dirvedw()
{
p1=data_7seg[month/10];p3=hlout&0xf7;delay(1);
p1=data_7seg[month%10];p3=hlout&0xfb;delay(1);
p1=data_7seg[day/10];p3=hlout&0xfd;delay(1);
p1=data_7seg[day%10];p3=hlout&0xfe;delay(1);
}
/*定时起时间输出驱动子函数*/
void t_dirve1()
{
p1=data_7seg[t_hour1/10];p3=hlout&0xf7;delay(1);
p1=data_7seg[t_hour1%10];p3=hlout&0xfb;delay(1);
p1=data_7seg[t_min1/10];p3=hlout&0xfd;delay(1);
p1=data_7seg[t_min1%10];p3=hlout&0xfe;delay(1);
}
/*定时止时间输出驱动子函数*/
void t_dirve2()
{
p1=data_7seg[t_hour2/10];p3=hlout&0xf7;delay(1);
p1=data_7seg[t_hour2%10];p3=hlout&0xfb;delay(1);
p1=data_7seg[t_min2/10];p3=hlout&0xfd;delay(1);
p1=data_7seg[t_min2%10];p3=hlout&0xfe;delay(1);
}
/*走时时时间调整*/
void timet_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)hour++;
if(hour==24)hour=0;
for(m=0;m<30;m++)
{
dirve();
if(p3_2==0)p1_7=0;
else p1_7=1;
delay(1);
}
}
/*走时分时间调整*/
void timem_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)min++;
if(min==60)min=0;
for(m=0;m<30;m++)
{
dirve();
if(p3_2==0)p1_7=0;
else p1_7=1;
delay(1);
}
}
/*走时年时间调整*/
void year_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)year++;
if(year==99)year=4;
for(m=0;m<30;m++)
{
dirveym();
if(p3_2==0)p1_7=0;
else p1_7=1;
delay(1);
}
}
/*走时月时间调整*/
void month_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)month++;
if(month==13)month=1;
for(m=0;m<30;m++)
{
dirvedw();
if(p3_2==0)p1_7=0;
else p1_7=1;
delay(1);
}
}
/*走时天时间调整*/
void day_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0){day++;}
if(day==month_n_day(year,month))day=1;
for(m=0;m<30;m++)
{
dirvedw();
if(p3_2==0)p1_7=0;
else p1_7=1;
delay(1);
}
}
/*定时起时时间调整*/
void alarm1t_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)t_hour1++;
if(t_hour1==24)t_hour1=0;
for(m=0;m<30;m++)
{
t_dirve1();
}
}
/*定时起分时间调整*/
void alarm1m_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)t_min1++;
if(t_min1==60)t_min1=0;
for(m=0;m<30;m++)
{
t_dirve1();
}
}
/*定时止时时间调整*/
void alarm2t_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)t_hour2++;
if(t_hour2==24)t_hour2=0;
for(m=0;m<30;m++)
{
t_dirve2();
}
}
/*定时止分时间调整*/
void alarm2m_adj()
{uchar m;
if(p3_5==0)delay(1);
if(p3_5==0)t_min2++;
if(t_min2==60)t_min2=0;
for(m=0;m<30;m++)
{
t_dirve2();
}
}
/*时、分、秒、日、月、年单元及走时单元转换*/
void conv()
{
if(deda<=100)d_05s=0;
else d_05s=1;
if(deda>=200){sec++;deda=0;}
if(sec==60){min++;sec=0;}
if(min==60){hour++;min=0;}
if(hour==24){day++;hour=0;}
if(day==month_n_day(year,month)){month++;day=1;}
if(month==12){year++;month=1;}
if(year==99)year=4;
}
/*判别闹时到否子函数*/
void p_out()
{
if(t_hour1==hour){if(t_min1==min)
hlout=0xff;}
if(t_hour2==hour){if(t_min2==min)
hlout=0x7f;}
}
/*主函数*/
void main()
{
init_timer(); /*定时器t0初始化*/
while(1) /*无限循环*/
{
if(p3_4==0)scan_key(); /*有按键,调用按键扫描子函数*/
switch(set) /*根据set键值散转*/
{
case 0:time();break; /*走时时间程序*/
case 1:timet_adj();break; /*走时时时间调整*/
case 2:timem_adj();break; /*走时分时间调整*/
case 3:year_adj();break; /*走时年时间调整*/
case 4:month_adj();break; /*走时月时间调整*/
case 5:day_adj();break; /*走时天时间调整*/
case 6:alarm1t_adj();break; /*闹时起时时间调整*/
case 7:alarm1m_adj();break; /*闹时起分时间调整*/
case 8:alarm2t_adj();break; /*闹时止时时间调整*/
case 9:alarm2m_adj();break; /*闹时止分时间调整*/
default:break; /*其它退出*/
}
if(flag!=0x55) /*判断掉电标志*/
{for(m=0;m<100;m++) /*点亮四个8字400ms*/
{
p1=0x80;p3=0xf7;delay(1);
p1=0x80;p3=0xfb;delay(1);
p1=0x80;p3=0xfd;delay(1);
p1=0x80;p3=0xfe;delay(1);
}
p1=0xff;p3=0xff;delay(400); /*熄灭四个8字400ms*/
}
}
}