万年历程序.docx
《万年历程序.docx》由会员分享,可在线阅读,更多相关《万年历程序.docx(14页珍藏版)》请在冰豆网上搜索。
![万年历程序.docx](https://file1.bdocx.com/fileroot1/2023-1/31/244a40af-6fe7-49c5-bd08-95db80d653c2/244a40af-6fe7-49c5-bd08-95db80d653c21.gif)
万年历程序
/**************************************
功能:
DS1302+lcd1602万年历时钟
1,显示年、月、日、星期、时、分、秒
2,DS1302掉电不丢失时间
3,按键校准
编写者:
温斌
编写日期:
2011-11-15
**************************************/
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSCLK=P2^0;
sbitIO=P2^1;
sbitRST=P2^2;
sbitlcdrs=P2^4;
sbitlcdrw=P2^5;
sbitlcden=P2^6;
sbitACC7=ACC^7;
sbits1=P1^0;
sbits2=P1^1;
sbits3=P1^2;
ucharflag;
ucharshi,fen,miao,week,month,year,day;
ucharcodetable[]="2011-11-1401";
ucharcodetable1[]="00:
00:
00";
ucharcodeadd[]={0x8c,0x88,0x86,0x8a,0x84,0x82,0x80};
/************************
ms级延时子程序
*************************/
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
/****************************************
DS1302驱动程序部分
****************************************/
voidwrite_ds1302(ucharadd,uchardate)
{
uchari,temp;
RST=0;
SCLK=0;
RST=1;
for(i=0;i<8;i++)
{
SCLK=0;
temp=add;
IO=(bit)(temp&0x01);
add>>=1;
SCLK=1;
}
for(i=0;i<8;i++)
{
SCLK=0;
temp=date;
IO=(bit)(temp&0x01);
date>>=1;
SCLK=1;
}
RST=0;
}
ucharread_ds1302(ucharadd)
{
uchari,temp,dat,dat1;
RST=0;
SCLK=0;
RST=1;
for(i=0;i<8;i++)
{
SCLK=0;
temp=add;
IO=(bit)(temp&0x01);
add>>=1;
SCLK=1;
}
for(i=0;i<8;i++)
{
ACC7=IO;
SCLK=1;
ACC>>=1;
SCLK=0;
}
RST=0;
dat=ACC;dat1=dat/16;
dat=dat%16;
dat=dat+dat1*10;
return(dat);
}
/*******************************
DS1302初始化
*******************************/
voidinit_ds1302()
{
write_ds1302(0x8e,0x00);//禁止写保护
write_ds1302(0x8c,0x11);//年
write_ds1302(0x88,0x11);//月
write_ds1302(0x86,0x14);//日
write_ds1302(0x8A,0x01);//星期
write_ds1302(0x84,0x16);//时
write_ds1302(0x82,0x46);//分
write_ds1302(0x80,0x00);//秒
write_ds1302(0x8e,0x80);//允许写保护
}
/*********************************
读取DS1302各寄存器数据
**********************************/
voidread_time()
{
miao=read_ds1302(0x81);//秒寄存器
fen=read_ds1302(0x83);//分
shi=read_ds1302(0x85);//时
week=read_ds1302(0x8B);//星期
day=read_ds1302(0x87);//日
month=read_ds1302(0x89);//月
year=read_ds1302(0x8d);//年
}
/*****************************************
LCD1602液晶驱动显示部分
*****************************************/
voidwrite_cmd(ucharcmd)
{
lcdrs=0;//低电平选择指令寄存器
lcdrw=0;
lcden=0;
P0=cmd;
delay(5);
lcden=1;
lcden=0;
}
voidwrite_date(uchardate)
{
lcdrs=1;//高电平选择数据寄存器
lcdrw=0;
lcden=0;
P0=date;
delay(5);
lcden=1;
lcden=0;
}
voidinit_lcd()
{
uchari;
write_cmd(0x01);//清屏
write_cmd(0x38);//8位数据位,双行显示,5*7点阵
write_cmd(0x0c);//显示开,光标不显示,不闪烁
write_cmd(0x06);//输入方式从左至右
write_cmd(0x80);
for(i=0;i<13;i++)write_date(table[i]);
write_cmd(0xc0);
for(i=0;i<8;i++)write_date(table1[i]);
}
/***********************
数据转换
使其正确显示在1602上
***********************/
voiddisplay_buff(ucharadd,uchardate)
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_cmd(0x80+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
/*****************************
显示各种数据,年、月、
日、星期、时、分、秒
******************************/
voiddisplay_time()
{
display_buff(2,year);
display_buff(5,month);
display_buff(8,day);
display_buff(11,week);
display_buff(0x40,shi);
display_buff(0x40+3,fen);
display_buff(0x40+6,miao);
}
/*************************
写字符串函数
*************************/
voidwstring(uchar*s)
{
while(*s)
{
write_date(*s);
s++;
}
}
/***********************
星期更新
**************************/
voidweek1()
{
write_cmd(0xc0+11);
switch(week)
{
case01:
wstring("Mon");break;
case02:
wstring("Tus");break;
case03:
wstring("Wen");break;
case04:
wstring("Thu");break;
case05:
wstring("Fri");break;
case06:
wstring("Sta");break;
case07:
wstring("Sun");break;
default:
break;
}
}
/******************************
键盘扫描
******************************/
voidkeyscan()
{
uchari,temp;
if(s1==0)
{
delay(10);
if(s1==0)
{
while(!
s1);
flag++;
write_ds1302(0x8e,0x00);//禁止写保护
if(flag==8)
{
flag=0;
write_ds1302(0x8e,0x80);//允许写保护
}
switch(flag)
{
case1:
write_cmd(0x80+3);
write_cmd(0x0f);break;
case2:
write_cmd(0x80+6);
write_cmd(0x0f);break;
case3:
write_cmd(0x80+9);
write_cmd(0x0f);break;
case4:
write_cmd(0x80+12);
write_cmd(0x0f);break;
case5:
write_cmd(0xc0+1);
write_cmd(0x0f);break;
case6:
write_cmd(0xc0+4);
write_cmd(0x0f);break;
case7:
write_cmd(0xc0+7);
write_cmd(0x0f);break;
default:
break;
}
}
}
if(s2==0)
{
delay(10);
if(s2==0)
{
while(!
s2);
switch(flag)
{
case7:
miao++;//设置键按动1次,调秒
if(miao==60)
miao=0;
display_buff(0x40+6,miao);
temp=(miao)/10*16+(miao)%10;
write_ds1302(0x80,temp);
write_cmd(0xc0+7);
break;
case6:
fen++;
if(fen==60)
fen=0;
display_buff(0x40+3,fen);
temp=(fen)/10*16+(fen)%10;
write_ds1302(0x82,temp);
write_cmd(0xc0+4);
break;
case5:
shi++;
if(shi==24)
shi=0;
display_buff(0x40,shi);
temp=(shi)/10*16+(shi)%10;
write_ds1302(0x84,temp);
write_cmd(0xc0+1);
break;
case4:
week++;
if(week==8)
week=1;
display_buff(11,week);
temp=(week)/10*16+(week)%10;
write_ds1302(0x8a,temp);
week1();
write_cmd(0x80+12);
break;
case3:
day++;
if(day==32)
day=1;
display_buff(8,day);
temp=(day)/10*16+(day)%10;
write_ds1302(0x86,temp);
write_cmd(0x80+9);
break;
case2:
month++;
if(month==13)
month=1;
display_buff(5,month);
temp=(month)/10*16+(month)%10;
write_ds1302(0x88,temp);
write_cmd(0x80+6);
break;
case1:
year++;
if(year==100)
year=0;
display_buff(2,year);
temp=(year)/10*16+(year)%10;
write_ds1302(0x8c,temp);
write_cmd(0x80+3);
break;
default:
break;
}
}
}
if(s3==0)
{
delay(10);
if(s3==0)
{
while(!
s3);
switch(flag)
{
case7:
miao--;//设置键按动1次,调秒
if(miao==0)
miao=59;
display_buff(0x40+6,miao);
temp=(miao)/10*16+(miao)%10;
write_ds1302(0x80,temp);
write_cmd(0xc0+7);
break;
case6:
fen--;
if(fen==0)
fen=59;
display_buff(0x40+3,fen);
temp=(fen)/10*16+(fen)%10;
write_ds1302(0x82,temp);
write_cmd(0xc0+4);
break;
case5:
shi--;
if(shi==0)
shi=59;
display_buff(0x40,shi);
temp=(shi)/10*16+(shi)%10;
write_ds1302(0x84,temp);
write_cmd(0xc0+1);
break;
case4:
week--;
if(week==0)
week=7;
display_buff(11,week);
temp=(week)/10*16+(week)%10;
write_ds1302(0x8a,temp);
week1();
write_cmd(0x80+12);
break;
case3:
day--;
if(day==0)
day=31;
display_buff(8,day);
temp=(day)/10*16+(day)%10;
write_ds1302(0x86,temp);
write_cmd(0x80+9);
break;
case2:
month--;
if(month==0)
month=12;
display_buff(5,month);
temp=(month)/10*16+(month)%10;
write_ds1302(0x88,temp);
write_cmd(0x80+6);
break;
case1:
year--;
if(year==0)
year=20;
display_buff(2,year);
temp=(year)/10*16+(year)%10;
write_ds1302(0x8c,temp);
write_cmd(0x80+3);
break;
default:
break;
}
}
}
}
/**********************************
主函数
***********************************/
voidmain()
{
init_lcd();
init_ds1302();//第一次烧到单片机中不屏蔽,允许DS1302初始化
//第二次烧需要屏蔽,禁止DS1302初始化
while
(1)
{
keyscan();
if(flag==0)
{
week1();
read_time();
display_time();
}
}
}