89C52LCD1602的万年历程序.docx
《89C52LCD1602的万年历程序.docx》由会员分享,可在线阅读,更多相关《89C52LCD1602的万年历程序.docx(23页珍藏版)》请在冰豆网上搜索。
89C52LCD1602的万年历程序
#include
#defineuintunsignedint
#defineucharunsignedchar
//u1,u2锁存器使能端在此目的是为了消除对P0口的影响
sbitu1=P2^6;
sbitu2=P2^7;
sbitled=P2^4;
//1602液晶输出
sbiten=P3^4;
sbitrs=P3^5;
sbitrw=P3^6;
//控制按键输出
sbitkey1=P3^0;//模式选择键
sbitkey2=P3^1;//加计数键
sbitkey3=P3^2;//复位返回键
sbitkey4=P3^3;//闹钟开关键
//sbitkey_com=P3^7;//按键公共地
//定义闹钟输出
sbitbeep=P2^3;
//sbitbeep=P2^4;
//全局变量定义
uchartime0,sec,min,hou;//时间(时,分,秒)变量定义
ucharnum,week_data,week;//星期变量定义
ucharmonth,day;//月份日期变量定义
uintyear;//年份变量定义
bity,m;//y为闰年的判定变量为1则为闰年m为大月的判断,为1则为大月m2为二月份的判定若是二月则m2=1;
//赋初值数组定义
ucharcodefirst_line[]="2014-03-23Sun";
ucharcodesecond_line[]="12:
00:
00";
ucharcodeweek_data1[]="Mon";
ucharcodeweek_data2[]="Tue";
ucharcodeweek_data3[]="Wen";
ucharcodeweek_data4[]="Thu";
ucharcodeweek_data5[]="Fri";
ucharcodeweek_data6[]="Sat";
ucharcodeweek_data7[]="Sun";
//延时子函数1ms延时
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//液晶写指令子函数com即所需输入的指令码
voidlcd_write_com(ucharcom)
{
rs=0;
rw=0;
en=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
//液晶写数据子函数
voidlcd_write_data(ucharlcd_data)
{
rs=1;
rw=0;
en=0;
P0=lcd_data;
delay(5);
en=1;
delay(5);
en=0;
}
//初始化子函数(包括:
液晶初始化操作和定时器0子函数操作)
voidinit()
{
ucharnum;
u1=0;
u2=0;//关闭U1U2锁存器防止对P0口的影响
//给时间设置初值2014-03-23Sun12:
00:
00
year=2014;
month=3;
day=23;
week=7;
hou=12;
min=00;
sec=0;
//液晶指令初始化
en=0;//将液晶en端拉低,为初始化写指令和数据准备
lcd_write_com(0x38);//MODE
lcd_write_com(0x0c);//DCB
lcd_write_com(0x06);//NS
lcd_write_com(0x01);//清屏
//液晶写初值
lcd_write_com(0x80);//写第一行地址
for(num=0;num<16;num++)
{
lcd_write_data(first_line[num]);
delay(5);
}
lcd_write_com(0x80+0x40);//写第二行地址
for(num=0;num<16;num++)
{
lcd_write_data(second_line[num]);
delay(5);
}
//定时器初始化
TMOD=0x01;//定时器0工作方式为1
TH0=(65535-50000)/256;//装初值
TL0=(65535-50000)%256;
ET0=1;//开定时器0中断
EA=1;//开总中断
TR0=1;//开始计时
}
//星期显示动态设置
voidwrite_week(ucharweek_num)
{
uchartemp,k;
temp=week_num;
if(temp==1)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data1[k]);
delay(5);
}
}
if(temp==2)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data2[k]);
delay(5);
}
}
if(temp==3)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data3[k]);
delay(5);
}
}
if(temp==4)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data4[k]);
delay(5);
}
}
if(temp==5)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data5[k]);
delay(5);
}
}
if(temp==6)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data6[k]);
delay(5);
}
}
if(temp==7)
{
for(k=0;k<3;k++)
{
lcd_write_data(week_data7[k]);
delay(5);
}
}/*
switch(temp)
{
case1:
for(k=0;k<3;k++)
{
lcd_write_data(week_data1[k]);
delay(5);
}
break;
case2:
for(k=0;k<3;k++)
{
lcd_write_data(week_data2[k]);
delay(5);
}
break;
case3:
for(k=0;k<3;k++)
{
lcd_write_data(week_data3[k]);
delay(5);
}
break;
case4:
for(k=0;k<3;k++)
{
lcd_write_data(week_data4[k]);
delay(5);
}
break;
case5:
for(k=0;k<3;k++)
{
lcd_write_data(week_data5[k]);
delay(5);
}
break;
case6:
for(k=0;k<3;k++)
{
lcd_write_data(week_data6[k]);
delay(5);
}
break;
case7:
for(k=0;k<3;k++)
{
lcd_write_data(week_data7[k]);
delay(5);
}
break;
}*/
}
//闰年判断的子函数
voidleapyear_choise(uints)
{
if(((s%4==0)&&(s%100!
=0))||(s%400==0))//四年一闰一百年不闰四百年一闰
y=1;//能被某个数整除即对这个数求余(%),而非求模(/)
else
y=0;
}
//大小月份的判断
voidbig_month(ucharmon)
{
switch(mon)
{
case1:
m=1;break;
case3:
m=1;break;
case5:
m=1;break;
case7:
m=1;break;
case8:
m=1;break;
case10:
m=1;break;
case12:
m=1;break;
case4:
m=0;break;
case6:
m=0;break;
case9:
m=0;break;
case11:
m=0;break;
}
}
//液晶显示动态数据即时刷新显示数据
voiddata_refresh(ucharadd,ucharre_data)//add为需要刷新的位置地址ch_data为需要改变的数据
{
uchars0,s1;//分别为各位的十进制数
s1=re_data/10;
s0=re_data%10;
lcd_write_com(0x80+add);
lcd_write_data(0x30+s1);//高位刷新
lcd_write_data(0x30+s0);//低位刷新
}
voidtime_key_set()
{
//功能键设定
//key_com=0;
if(key1==0)
{
delay(5);//按键延时消抖
if(key1==0)
{
num++;
while(!
key1);//松手检测
if(num==1)
{
TR0=0;//当进入调时模式时关闭T0计时器,停止计时
lcd_write_com(0x80+0x40+10);//设定需要调改的位置地址秒钟
lcd_write_com(0x0d);//被选中的位光标闪烁
}
elseif(num==2)
{
lcd_write_com(0x80+0x40+7);//分钟
}
elseif(num==3)
{
lcd_write_com(0x80+0x40+4);//时钟
}
elseif(num==4)
{
lcd_write_com(0x80+13);//星期
}
elseif(num==5)
{
lcd_write_com(0x80+9);//日期
}
elseif(num==6)
{
lcd_write_com(0x80+6);//月份
}
elseif(num==7)
{
lcd_write_com(0x80+3);//年(低位)
}
elseif(num==8)
{
lcd_write_com(0x80+1);//年(高位)
}
elseif(num==9)
{
sec=0;
num=0;
TR0=1;//开启定时器
lcd_write_com(0x0c);//取消闪烁
}
}
}
//加计数键设定
if(num!
=0)//只有在功能设定键起作用期间才可以调时除此之外该键将不起作用
{
if(key2==0)
{
delay(5);
if(key2==0)
{
while(!
key2);//松手检测
if(num==1)
{
sec++;
if(sec==60)
sec=0;
data_refresh(0x40+10,sec);//即使将更新的时间显示数据发送给液晶
lcd_write_com(0x80+0x40+10);//选择需要更改的地址位
}
if(num==2)
{
min++;
if(min==60)
min=0;
data_refresh(0x40+7,min);
lcd_write_com(0x80+0x40+7);
}
if(num==3)
{
hou++;
if(hou==24)
hou=0;
data_refresh(0x40+4,hou);
lcd_write_com(0x80+0x40+4);
}
if(num==4)
{
week++;
if(week==8)
week=1;
write_week(week);
lcd_write_com(0x80+13);
}
if(num==5)
{
day++;
big_month(month);//调用大小月判断子函数
if(m==1)
{
if(day==32)
day=1;
}
else
{
if(day==31)
day=1;
}
if(month==2)
{
leapyear_choise(year);//调用闰年判断子函数
if(y==1)
{
if(day==30)
day=1;
}
if(y==0)
{
if(day==29)
day=1;
}
}
data_refresh(9,day);
lcd_write_com(0x80+9);
}
if(num==6)
{
month++;
if(month==13)
month=1;
data_refresh(6,month);
lcd_write_com(0x80+6);
}
if(num==7)
{
year++;
if(year==9999)
year=0;
data_refresh(3,year%100);
lcd_write_com(0x80+3);
}
if(num==8)
{
year=year+100;
if((year/100)>99)
year=0;
data_refresh(1,year/100);
lcd_write_com(0x80+1);
}
}
}
if(key3==0)
{
delay(5);
if(key3==0)
{
sec=0;
num=0;
TR0=1;//开启定时器
lcd_write_com(0x0c);//取消闪烁
}
}
}
}
//闹钟设定
voidclock()
{
bitflag;
if(key4==0)//闹钟开关键
{
delay(5);
if(key4==0)
{
flag=!
flag;
while(!
key4);
}
}
if(flag==1)
{
led=0;
if(min==0)
{
if(hou==0)
{
beep=0;
delay(1000);
beep=1;
}
if((hou>0)&&(hou<13))
{
if((sec>0)&&(sec<=hou))
{
beep=0;
delay(110);
beep=1;
delay(110);
beep=0;
delay(110);
beep=1;
delay(770);
}
}
if((hou>12)&&(hou<=23))
{
if((sec>0)&&(sec<=hou-12))
{
beep=0;
delay(110);
beep=1;
delay(110);
beep=0;
delay(110);
beep=1;
delay(770);
}
}
}
}
if(flag==0)
{
led=1;
}
}
//主函数
voidmain()
{
init();
while
(1)
{
time_key_set();
clock();
}
}
//定时器中断子函数
voidt0()interrupt1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
time0++;
if(time0==20)
{
time0=0;
sec++;
if(sec==60)
{
sec=0;
min++;
if(min==60)
{
min=0;
hou++;
if(hou==24)
{
hou=0;
day++;
week++;
if(week==8)
week=1;
lcd_write_com(0x80+13);//注意这两行的顺序不能反过来
write_week(week);//注意这两行的顺序不能反过来
big_month(month);//调用大小月判断子函数
if(m==1)
{
if(day==32)
{
day=1;
month++;
if(month==13)
{
month=1;
year++;
if(year==9999)
{
year=0;
}
data_refresh(1,year/100);
data_refresh(3,year%100);
}
data_refresh(6,month);
}
}
else
{
if(day==31)
{
day=1;
month++;
}
data_refresh(6,month);
}
if(month==2)
{
leapyear_choise(year);//调用闰年判断子函数
if(y==1)
{
if(day==30)
{
day=1;
month=3;
}
data_refresh(6,month);
}
elseif(y==0)
{
if(day==29)
{
day=1;
month=3;
}
data_refresh(6,month);
}
}
data_refresh(9,day);
}
data_refresh(0x40+4,hou);
}
data_refresh(0x40+7,min);
}
data_refresh(0x40+10,sec);
}
}