#include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar second,minute,hour,week,day,month,year;
uchar time[] ={0x12,0x07,0x26,0x08,0x07,0x07,0x04}; //初始时间数组
sbit DS1302_RST = P3^3;
sbit DS1302_IO = P2^4;
sbit DS1302_SCLK = P3^2;
sbit LCD_EN = P3^4;
sbit LCD_RW = P3^6;
sbit LCD_RS = P3^5;
uchar code dis1[]={" DS1302+LCD12864"};
uchar code dis2[]={" 暑假学习 "};
/***************************延时函数*******************************/
void delay(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
/******************向DS1302送一字节数据*****************************/
void input_byte(uint temp)
{
char i;
for(i=8;i>0;i--)
{
DS1302_IO = (bit)(temp&0x01);
DS1302_SCLK=1;
_nop_();
DS1302_SCLK=0;
temp>>= 1;
}
}
/***********************:读DS1302一个字节***************************/
uchar output_byte(void )
{
uchar i;
uchar ucdat = 0;
for(i = 8; i > 0; i--)
{
DS1302_IO = 1;
ucdat >>= 1;
if(DS1302_IO)
ucdat |= 0x80;
DS1302_SCLK = 1;
_nop_();
DS1302_SCLK= 0;
}
return(ucdat);
}
/******************向DS1302某地址写一字节数据***********************/
void write_1302(uchar add,uchar dat)
{
DS1302_RST = 0;
_nop_();
DS1302_SCLK = 0;
_nop_();
DS1302_RST = 1;
input_byte(add);
_nop_();
input_byte(dat);
DS1302_SCLK = 1;
_nop_();
DS1302_RST = 0;
}
/*****************************读DS1302地址***************************/
uchar read_1302(uchar add)
{
uchar abc;
DS1302_RST=0;
_nop_();
DS1302_SCLK=0;
_nop_();
DS1302_RST=1;
input_byte(add);
abc=output_byte();
DS1302_SCLK=1;
_nop_();
DS1302_RST=0;
return(abc);
}
/***************************初始化DS1302******************************/
void init_ds1302()
{
write_1302(0x8e,0x00); //写保护寄存器,在对时钟或RAM写前WP一定要为0
write_1302(0x8c,time[0]); //年
write_1302(0x88,time[1]); //月
write_1302(0x86,time[2]); //日
write_1302(0x84,time[3]); //时
write_1302(0x82,time[4]); //分
write_1302(0x80,time[5]); //秒
write_1302(0x8A,time[6]); //星期
write_1302(0x8e,0x80); //写保护寄存器
}
/*************************读DS1302时间***********************************/
void read_time()
{
second=read_1302(0x81); //秒寄存器
minute=read_1302(0x83); //分
hour=read_1302(0x85); //时
day=read_1302(0x87); //日
month=read_1302(0x89); //月
week=read_1302(0x8b); //星期
year=read_1302(0x8d); //年
}
/***********************写指令数据到LCD*********************************/
void write_cmd(uchar cmd)
{
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
P0 = cmd;
delay(5);
LCD_EN=1;
delay(5);
LCD_EN=0;
}
/***************************写显示数据到LCD******************************/
void write_dat(uchar dat)
{
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
delay(5);
LCD_EN = 1;
delay(5);
LCD_EN = 0;
}
/***************************设定显示位置**********************************/
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if(X == 0)
{X = 0x80;}
else if (X == 1)
{X = 0x90;}
else if (X == 2)
{X = 0x88;}
else if (X == 3)
{X = 0x98;}
pos = X+Y;
write_cmd(pos);
}
void writesting(uchar x,uchar y,uchar *p)
{
uchar temp;
temp=*p;
lcd_pos(x,y);
while(temp)
{
write_dat(temp);
temp=*(++p);
}
}
/*******************************LCD初始化**********************************/
void lcd_init()
{
write_cmd(0x30);
delay(5);
write_cmd(0x0c);
delay(5);
write_cmd(0x01);
delay(5);
}
/*********************************显示函数*********************************/
void display()
{
lcd_pos(2,2);
write_dat((year/16) + 0x30);
write_dat((year%16) + 0x30);
writesting(2,1,"20");
lcd_pos(2,4);
write_dat((month/16) + 0x30);
write_dat((month%16) + 0x30);
writesting(2,3,"-");
lcd_pos(2,6);
write_dat((day/16) + 0x30);
write_dat((day%16) + 0x30);
writesting(2,5,"-");
lcd_pos(3,0);
write_dat((hour/16) + 0x30);
write_dat((hour%16) + 0x30);
writesting(3,1,":");
lcd_pos(3,2);
write_dat((minute/16) + 0x30);
write_dat((minute%16) + 0x30);
writesting(3,3,":");
lcd_pos(3,4);
write_dat((second/16) + 0x30);
write_dat((second%16) + 0x30);
writesting(3,5,"星");
writesting(3,6,"期");
switch(week)
{
case 1: writesting(3,7,"一");break;
case 2: writesting(3,7,"二");break;
case 3: //writesting(3,7,"三"); 无法识别这一条语句
{write_dat(0xc8);write_dat(0xfd);} //与上一条语句等价,用来显示“三”
break;
case 4: writesting(3,7,"四");break;
case 5: writesting(3,7,"五");break;
case 6: writesting(3,7,"六");break;
case 7: writesting(3,7,"七");break;
}
write_dat((week/16) + 0x30);
write_dat(week%16+0x30);
}
/*****************************显示位置*********************************/
void LCD_pos()
{
uchar i;
lcd_pos(0,0); //显示字符
i=0;
while(dis1[i]!='\0')
{
write_dat(dis1[i]);
i++;
}
lcd_pos(1,0); //显示字符
i=0;
while(dis2[i]!='\0')
{
write_dat(dis2[i]);
i++;
}
}
/********************************主函数************************************/
void main()
{
init_ds1302();
lcd_init();
LCD_pos();
while(1)
{
read_time();
display();
}
} |