#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include<intrins.h>
#include<math.h>
#include<ku.h>
#define LCD_databus P0
sbit sck=P1^0;
sbit io=P1^1;
sbit rst=P3^6;
sbit RS=P2^2; //RS为0---命令;1----数据
sbit RW=P2^1; //RW为1---写;0---读
sbit EN=P2^0; //使能端
sbit CS1=P2^4; //片选1低电平有效,控制左半屏
sbit CS2=P2^3; //片选1低电平有效,控制右半屏
void write_ds1302(uchar add,uchar dat);
void write_ds1302_byte(uchar dat);
uchar read_ds1302(uchar add);
void set_rtc(void);
void read_rtc(void);
void time_pros(void);
void display(void);
uchar disp[20];
uchar time_data[7]={12,6,7,28,12,3,3}; //设定起始时间
uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};//年 周 月 天 时 分 秒
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
void Read_busy()//读“忙”函数-----数据线的最高位DB71则busy
{
P0=0x00;
RS=0;
RW=1;
EN=1;
while(P0 & 0x80);
EN=0;
}
void write_LCD_command(uchar value) //写命令函数
{
Read_busy(); //对LCD的每次读写都要读忙
RS=0; //选择命令
RW=0; //读操作
LCD_databus=value;
EN=1; //EN由1----0锁存有效数据
_nop_();
_nop_();
EN=0;
}
void write_LCD_data(uchar value)//写数据函数
{
Read_busy();
RS=1; //选择数据
RW=0;
LCD_databus=value;
EN=1; //EN由1----0锁存有效数据
_nop_();
_nop_();
EN=0;
}
uchar Read_LCD(void) //读数据函数
{
uchar value;
Read_busy();
LCD_databus=0xFF; //先进行一次空读操作
RS=1;
RW=1;
EN=1;
_nop_();
_nop_();
EN=0;
LCD_databus=0xFF; //读取真正的数据
RS=1;
RW=1;
EN=1;
value=LCD_databus;
_nop_();
_nop_();
EN=0;
return value;
}
void Set_page(uchar page) //设置“页”LCD12864共8页,一页是8行点阵点
{
page=0xb8|page; //页的首地址为0xB8
write_LCD_command(page);
}
void Set_line(uchar startline) //设置显示的起始行
{
startline=0xC0|startline; //起始行地址为0xC0
write_LCD_command(startline); //设置从哪行开始:共0--63;一般从0 行开始显示
}
void Set_column(uchar column) //设置显示的列
{
column=column &0x3f; //列的最大值为64
column= 0x40|column; //列的首地址为0x40
write_LCD_command(column); //规定显示的列的位置
}
void SetOnOff(uchar onoff) //显示开关函数:0x3E是关显示,0x3F是开显示
{
onoff=0x3e|onoff; //onoff:1---开显示;0---关显示
write_LCD_command(onoff);
}
void SelectScreen(uchar screen) //选择屏幕
{
switch(screen)
{
case 0: CS1=0;CS2=0;break; //全屏
case 1: CS1=0;CS2=1;break;//左半屏
case 2: CS1=1;CS2=0;break;//右半屏
case 3: CS1=1;CS2=1;break;//无屏
default:break;
}
}
void ClearScreen(uchar screen) //清屏函数
{
uchar i,j;
SelectScreen(screen); //0--全屏;1---左半屏;2---右半屏
for(i=0;i<8;i++) //控制页数0-7,共8页
{
Set_page(i);
Set_column(0);
for(j=0;j<64;j++) //控制列数0-63,共64列
{
write_LCD_data(0x00); //写入0,地址指针自加1
}
}
}
void InitLCD() //LCD的初始化
{
SetOnOff(1); //开显示
SelectScreen(0);
ClearScreen(0); //清屏
Set_line(0); //开始行:0
}
void Display_SZ(uchar ss,uchar page,uchar column,uchar *p)
{
uchar i;
SelectScreen(ss);
Set_page(page); //写上半页
Set_column(column*8); //控制列
for(i=0;i<8;i++) //控制8列的数据输出
{
write_LCD_data(p[i]); //汉字的上半部分
}
Set_page(page+1); //写下半页
Set_column(column*8); //控制列
for(i=0;i<8;i++) //控制8列的数据输出
{
write_LCD_data(p[i+8]); //汉字的下半部分
}
}
void Display_HZ(uchar ss,uchar page,uchar column,uchar *p)
{
uchar i;
SelectScreen(ss);
Set_page(page); //写上半页
Set_column(column*16); //控制列
for(i=0;i<16;i++) //控制16列的数据输出
{
write_LCD_data(p[i]); //汉字的上半部分
}
Set_page(page+1); //写下半页
Set_column(column*16); //控制列
for(i=0;i<16;i++) //控制16列的数据输出
{
write_LCD_data(p[i+16]); //汉字的下半部分
}
}
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--)
;
}
void write_ds1302_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
sck=0;
io=dat&0x01;
dat=dat>>1;
sck=1;
}
}
void write_ds1302(uchar add,uchar dat)
{
rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
write_ds1302_byte(add);
write_ds1302_byte(dat);
rst=0;
_nop_();
io=1;
sck=1;
}
uchar read_ds1302(uchar add)
{
uchar i,value;
rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
write_ds1302_byte(add);
for(i=0;i<8;i++)
{
value=value>>1;
sck=0;
if(io)
value=value|0x80;
sck=1;
}
rst=0;
_nop_();
sck=0;
_nop_();
sck=1;
io=1;
return value;
}
void set_rtc(void)
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_data[i]/10;
time_data[i]=time_data[i]%10;
time_data[i]=time_data[i]+j*16;
}
write_ds1302(0x8e,0x00);
for(i=0;i<7;i++)
{
write_ds1302(write_add[i],time_data[i]);
}
write_ds1302(0x8e,0x80);
}
void read_rtc(void)
{
uchar i;
for(i=0;i<7;i++)
{
time_data[i]=read_ds1302(read_add[i]);
}
}
void time_pros(void)
{
disp[0]=time_data[6]%16; //秒
disp[1]=time_data[6]/16;
disp[2]=time_data[5]%16; //分
disp[3]=time_data[5]/16;
disp[4]=time_data[4]%16; //时
disp[5]=time_data[4]/16;
disp[6]=time_data[3]%16; //天
disp[7]=time_data[3]/16;
disp[8]=time_data[2]%16; //月
disp[9]=time_data[2]/16;
disp[10]=time_data[1]%16; //周
disp[11]=time_data[1]/16;
disp[12]=time_data[0]%16; //年
disp[13]=time_data[0]/16;
}
void main()
{
InitLCD(); //初始12864
ClearScreen(0); //清屏
Set_line(0);
set_rtc(); //设定起始时间
Display_SZ(1,2,2,maohao);
Display_SZ(1,2,5,maohao);
Display_SZ(1,0,2,xie);
Display_SZ(1,0,5,xie);
Display_HZ(2,0,1,xing);
Display_HZ(2,0,2,qi);
while(1)
{
read_rtc();
time_pros();
switch(disp[0]) //秒
{
case 0:Display_SZ(1,2,7,shu_0);break;
case 1:Display_SZ(1,2,7,shu_1);break;
case 2:Display_SZ(1,2,7,shu_2);break;
case 3:Display_SZ(1,2,7,shu_3);break;
case 4:Display_SZ(1,2,7,shu_4);break;
case 5:Display_SZ(1,2,7,shu_5);break;
case 6:Display_SZ(1,2,7,shu_6);break;
case 7:Display_SZ(1,2,7,shu_7);break;
case 8:Display_SZ(1,2,7,shu_8);break;
case 9:Display_SZ(1,2,7,shu_9);break;
}
switch(disp[1]) //秒
{
case 0:Display_SZ(1,2,6,shu_0);break;
case 1:Display_SZ(1,2,6,shu_1);break;
case 2:Display_SZ(1,2,6,shu_2);break;
case 3:Display_SZ(1,2,6,shu_3);break;
case 4:Display_SZ(1,2,6,shu_4);break;
case 5:Display_SZ(1,2,6,shu_5);break;
case 6:Display_SZ(1,2,6,shu_6);break;
case 7:Display_SZ(1,2,6,shu_7);break;
case 8:Display_SZ(1,2,6,shu_8);break;
case 9:Display_SZ(1,2,6,shu_9);break;
}
switch(disp[2]) //分
{
case 0:Display_SZ(1,2,4,shu_0);break;
case 1:Display_SZ(1,2,4,shu_1);break;
case 2:Display_SZ(1,2,4,shu_2);break;
case 3:Display_SZ(1,2,4,shu_3);break;
case 4:Display_SZ(1,2,4,shu_4);break;
case 5:Display_SZ(1,2,4,shu_5);break;
case 6:Display_SZ(1,2,4,shu_6);break;
case 7:Display_SZ(1,2,4,shu_7);break;
case 8:Display_SZ(1,2,4,shu_8);break;
case 9:Display_SZ(1,2,4,shu_9);break;
}
switch(disp[3]) //分
{
case 0:Display_SZ(1,2,3,shu_0);break;
case 1:Display_SZ(1,2,3,shu_1);break;
case 2:Display_SZ(1,2,3,shu_2);break;
case 3:Display_SZ(1,2,3,shu_3);break;
case 4:Display_SZ(1,2,3,shu_4);break;
case 5:Display_SZ(1,2,3,shu_5);break;
case 6:Display_SZ(1,2,3,shu_6);break;
case 7:Display_SZ(1,2,3,shu_7);break;
case 8:Display_SZ(1,2,3,shu_8);break;
case 9:Display_SZ(1,2,3,shu_9);break;
}
switch(disp[4]) //时
{
case 0:Display_SZ(1,2,1,shu_0);break;
case 1:Display_SZ(