C51数字时钟/日历---LCD1602液晶显示屏
/*Main.c*/
#include<reg51.h>
#include"LCD1602.h"
#include"KeyScan.h"
#include"SetValue.h"
#include"Sounder.h"
#include"Ds18b20.h"
intIntCount=0,StopCount=0,StopMin=0;
ucharSec=0,Min=0,Hour=0,Date=1,month=1,SetMin=1,SetHour=0,NUM1,CountWeek;
intyear=2014,Qiehuan;
char KEY;
unsignedchar code dis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"};
unsignedchar code para_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5}; //星期月参变数
ucharcode Timetable1[]=" CurrentTime ";
ucharcode Datetable1[]=" CurrentDate ";
ucharcode Settable1[]=" Set RingTime ";
ucharcode CurrentTime[]=" 00:00:00 ";
ucharcode SetTime[]=" 00:00 ";
ucharcode CurrentDate[]=" 2014-01-01 ";
ucharcode CurrentTemp[]=" Temperature ";
ucharcode Temptable[]=" 00.0'C ";
ucharcode Stopwatch[]=" StopWatch ";
ucharcode Stoptable[]=" 000.00s ";
bitalarm;
/*定时器0、1初始化*/
voidTimer_Init(void)
{
TMOD=0x11; /*定时器T0、T1初始化为方式1*/
TL0=0xb0; /*装入定时初值,在主频12MHZ下,定时50ms*/
TH0=0x3c;
TL1=0xf0; /*装入定时初值,在主频12MHZ下,定时10ms*/
TH1=0xd8;
ET0=1; /*开启定时器T0中断*/
ET1=1; /*开启定时器T1中断*/
TR0=1; /*启动定时器T0定时*/
TR1=0;
}
/*外部中断0初始化*/
voidInt_Init(void)
{
IT0=1; //设置下降沿触发方式
EX0=1; //开放外部中断0
IT1=1; //设置下降沿触发方式
EX1=1; //开放外部中断0
EA=1;
}
/*外部中断0中断函数*/
voidInt0_int(void) interrupt 0
{
alarm=!alarm; //闹钟的开关切换
}
/*中断号1是定时器T0中断*/
voidTimer0_int(void) interrupt 1
{
EA=0; //关中断
TL0=0xb7; //重装定时初值,在主频12MHZ下,定时50ms
TH0=0x3c; //修正量为7个机器周期
IntCount++;
if(IntCount==20)
{
Sec++; //秒位加一
IntCount=0;
}
EA=1; //开中断
}
/*外部中断1的中断函数,设定秒表的起始*/
voidInt1_int(void) interrupt 2
{
TR1=!TR1;
if(TR1)
StopMin=0;
}
/*中断号3是定时器T1中断*/
void Timer1_int(void) interrupt 3
{
EA=0; /*关中断*/
TL1=0xf0; /*装入定时初值,在主频12MHZ下,定时10ms*/
TH1=0xd8;
StopMin++;
EA=1;
}
/*按键处理程序*/
voidKey_Process(uchar Qkeynum)
{
if(Qkeynum=='1') //按键一用于显示切换
{
Qiehuan++;
if(Qiehuan==1) //显示当前时间
{
uchar num;
write_com(0x01); //显示清屏
write_com(0x80);
for(num=0;num<15;num++)
{
write_data(Timetable1[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(CurrentTime[num]);
delay(5);
}
}
else if(Qiehuan==2) //显示当前日期
{
uchar num;
write_com(0x01);//显示清屏
write_com(0x80);
for(num=0;num<15;num++)
{
write_data(Datetable1[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(CurrentDate[num]);
delay(5);
}
}
else if(Qiehuan==3) //显示当前定时
{
uchar num;
write_com(0x01);//显示清屏
write_com(0x80);
for(num=0;num<15;num++)
{
write_data(Settable1[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(SetTime[num]);
delay(5);
}
}
else if(Qiehuan==4) //显示当前温度
{
uchar num;
write_com(0x01);//显示清屏
write_com(0x80);
for(num=0;num<15;num++)
{
write_data(CurrentTemp[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(Temptable[num]);
delay(5);
}
}
else if(Qiehuan==5) //显示秒表
{
uchar num;
write_com(0x01);//显示清屏
write_com(0x80);
for(num=0;num<15;num++)
{
write_data(Stopwatch[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<16;num++)
{
write_data(Stoptable[num]);
delay(5);
}
Qiehuan=0;
}
}
elseif(Qkeynum=='2')
{
Sec++;
if(Sec>59)
Sec=0;
}
if(Qkeynum=='3')
{
Min++;
if(Min>59)
Min=0;
}
if(Qkeynum=='4')
{
Hour++;
{
if(Hour>23)
Hour=0;
}
}
if(Qkeynum=='5')
{
Date++;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
if (Date>31)
{
Date=1;
} //大月31天
else if(month==4||month==6||month==9||month==11)
if (Date>30) {Date=1;} //小月30天
}
if(Qkeynum=='6')
{
month++;
if (month>12)
month=1;
}
if(Qkeynum=='7')
{
year++;
if(year>2099)
year=2000;
}
if(Qkeynum=='8')
{
SetMin++;
if(SetMin>59)
SetMin=0;
}
if(Qkeynum=='9')
{
SetHour++;
if(SetHour>23)
SetHour=0;
}
if(Qkeynum=='A') //设置贪睡功能
{
SetMin=SetMin+2;
if(SetMin>60)
{
SetMin=SetMin-60;
SetHour++;
if(SetHour>23)
SetHour=0;
}
}
}
/*闰年的计算*/
bitleap_year()
{
bit leap;
if((year%4==0&&year%100!=0)||year%400==0)//闰年的条件
leap=1;
else
leap=0;
return leap;
}
/*星期的自动运算和处理*/
/*基姆拉尔森计算公式*/
unsignedchar week_proc()
{ unsigned char num_leap;
unsigned char c;
unsigned char week;
//from http://blog.****.net/wylloong/article/details/35818451
num_leap=year/4-year/100+year/400;//自00年起到year所经历的闰年数
if( leap_year()&& month<=2 ) //既是闰年且是1月和2月
c=5;
else
c=6;
week=(year+para_month[month]+Date+num_leap+c+4)%7;//计算对应的星期
return week;
}
/*显示当前时间*/
voidShowTime(void)
{
write_com(0x80+0x40);
write_Dec(4,Hour);
write_Dec(7,Min);
write_Dec(10,Sec);
}
/*显示闹钟设定时间*/
voidShowSetTime(void)
{
write_com(0x80+0x40);
write_Dec(5,SetHour);
write_Dec(8,SetMin);
}
/*显示日期*/
voidShowDate(void)
{
write_com(0x80+0x40);
write_Dec(2,20);
write_Dec(4,(year%100));
write_Dec(7,month);
write_Dec(10,Date);
}
/*显示秒表时间*/
voidShowStopWatch()
{
write_com(0x80+0x40+4);
write_data(StopMin/10000+0x30);
write_data((StopMin%10000)/1000+0x30);
write_data((StopMin%1000)/100+0x30);
write_com(0x80+0x40+8);
write_data((StopMin%100)/10+0x30);
write_data((StopMin%10)+0x30);
}
voidCalcu_time(void)
{
if(Sec>59)
{
Sec=0;
Min++;
if(Min>59)
{
Min=0;
Hour++;
if(Hour>23) //*24H从零点开始
{
Date++;
Hour=0;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
if (Date>31)
{Date=1;month++;
} //大月31天
else if(month==4||month==6||month==9||month==11)
if (Date>30) {Date=1;month++;} //小月30天
else if (month==2)
{
if(leap_year()) //闰年的条件
{
if (Date>29)
{
Date=1;month++;
}
} //闰年2月为29天
else
{
if (Date>28) {Date=1;month++;} //平年2月为28天
}
} //if (month==2)
else if (month>12)
{
month=1;
year++;
if(year>2099)
year=2000;
} //if (month>12)
} //if(Hour==24)
} //if(Min==60)
} //if(Sec==60)
if(Qiehuan==2) //日期和星期同时显示
{
CountWeek=week_proc();
write_com(0x80+0x40+13);
write_data(dis_week[4*CountWeek]);
write_data(dis_week[4*CountWeek+1]);
write_data(dis_week[4*CountWeek+2]);
}
if((Min==SetMin)&&(Hour==SetHour)) //闹钟定时到达后响铃
{
if (alarm)
BellRing();
else Sounder=0;
}
else Sounder=0; //扬声器关闭
if (alarm&&(Qiehuan==1)) //闹钟开关标志和时间同时显示
{
write_com(0x80+0x40)