#include
#include //右移、左移
#define uint unsigned int
#define uchar unsigned char
#define DS1302_SECOND_READ 0x81
#define DS1302_MINUTE_READ 0x83
#define DS1302_HOUR_READ 0x85
#define DS1302_DAY_READ 0x87
#define DS1302_MON_READ 0x89
#define DS1302_YEAR_READ 0x8d
#define WRITE_PROTECT 0x8e
***it rs=P2^2;//写指令/数据 //12864
***it rw=P2^3;//读状态/写
***it e=P2^4;//使能端
***it p***=P2^5;//串/并输入
***it SCLK=P1^5; //1302
***it DATA=P1^4;
***it RST=P1^6;
uchar code table1[]="20 年 月 日";
uchar code table2[]=" 时 分 秒";
uchar num;
uchar day,mon,year,sec,min,hour;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--); //延时
}
void check_busy() //LCD12864程序
{
rs=0;
rw=1;
e=1;
P0=0xff;
while((P0&0x80)==0x80);
e=0;
}
//写指令
void write_com(uchar com)
{
check_busy();
rs=0;
rw=0;
e=1;
P0=com;
delay(5);
e=0;
delay(5);
}
//写数据
void write_date(uchar _date)
{
check_busy();
rs=1;
rw=0;
e=1;
P0=_date;
delay(5);
e=0;
delay(5);
}
//初始化lcd
//DS1302
void Write1302(uchar dat)
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delay(5); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302
delay(5); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delay(5); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
void WriteSet1302(unsigned char Cmd,unsigned char dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数据前SCLK被拉低
RST=1; //启动数据传输
delay(5); //稍微等待,使硬件做好准备
Write1302(Cmd); //写入命令字
Write1302(dat); //写数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
}
unsigned char Read1302(void)
{
uchar i,dat;
delay(5);; //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{
dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delay(5); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delay(5); //稍微等待
}
return dat; //将读出的数据返回
}
unsigned char ReadSet1302(uchar Cmd)
{
uchar dat;
RST=0; //拉低RST
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
Write1302(Cmd); //写入命令字
dat=Read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
dat = dat/16*10+dat%16; //分离十位和个位,将十六进制数转化为十进制数
return dat; //将读出的数据返回
}
void write_sfm(uchar add,uchar date)
{
uchar ge,shi;
shi=date/10;
ge=date%10;
write_com(0+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void display()
{
day=ReadSet1302(DS1302_DAY_READ);
mon=ReadSet1302(DS1302_MON_READ);
year=ReadSet1302(DS1302_YEAR_READ);
sec=ReadSet1302(DS1302_SECOND_READ);
min=ReadSet1302(DS1302_MINUTE_READ);
hour=ReadSet1302(DS1302_HOUR_READ);
write_sfm(0x80+5,day);
write_sfm(0x80+3,mon);
write_sfm(0x80+1,year);
write_sfm(0x90+4,sec);
write_sfm(0x90+2,min);
write_sfm(0x90,hour);
}
void Init_DS1302() //DS1302初始化
{
WriteSet1302(0x8E,0x00); //根据写状态寄存器命令字,写入不保护指令
WriteSet1302(0x8E,0x80); //根据写状态寄存器命令字,写入保护指令
}
void init() //LCD12864程序
{
rw=0;
p***=1;//选择为并行输入
delay(50);
write_com(0x30);//基本指令操作
delay(5);
write_com(0x0c);//显示开,关光标
delay(5);
write_com(0x06);//写入一个字符,地址加1
delay(5);
write_com(0x01);
write_com(0x80);
for(num=0;num<14;num++) \第一行显示年月日
{
write_date(table1[num]);
delay(20);
}
write_com(0x90);
for(num=0;num<12;num++) \第二行显示时分秒
{
write_date(table2[num]);
delay(20);
}
}
void main()
{
init();
Init_DS1302();
while(1)
{
display();
}
}