/* （Ds1302+LCD1602）*/
#include<reg52.h>
#include<intrins.h>
sbit DS1302_CLK=P1^1;
sbit DS1302_IO=P1^0;
sbit DS1302_RST=P1^2;
sbit lcden=P2^2;
sbit lcdrw=P2^1;
sbit lcdrs=P2^0;

#define uchar unsigned char
#define uint unsigned int
#define RS_CLR lcdrs=0
#define RS_SET lcdrs=1

#define RW_CLR lcdrw=0
#define RW_SET lcdrw=1

#define EN_CLR lcden=0
#define EN_SET lcden=1

#define DataPort P2

unsigned char second,minute,hour,week,day,month,year;
unsigned char table[]="0123456789";
//unsigned char table1[]="          ";
unsigned char table2[]="                 ";
unsigned char table3[]="Time: ";
unsigned char table4[]="Date: ";
unsigned int time[]= { 0x13,0x05,0x18,0x03,0x00,0x00,0x00};
unsigned char receive[3]= {0xff,0xff,0xff};
unsigned char ComBuf[3]= {0x02,0x90,0x08};
uchar num,count,date,shi;

void delay(uint z)
{
    uint x,y;
    for(x=z; x>0; x--)
        for(y=110; y>0; y--);
}
void DelayUs2x(unsigned char t)
{
    while(--t);
}
/*------------------------------------------------
 mS延时函数，含有输入参数 unsigned char t，无返回值
 unsigned char 是定义无符号字符变量，其值的范围是
 0~255 这里使用晶振12M，精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{

    while(t--)
    {
        //大致延时1mS
        DelayUs2x(245);
        DelayUs2x(245);
    }
}
//向DS1302送一个字节//
void InputByte(unsigned char byte1)
{
    char i;
    for(i=8; i>0; i--)
    {
        DS1302_IO=(bit)(byte1&0x01);
        DS1302_CLK=1;
        _nop_();
        DS1302_CLK=0;
        byte1>>=1;
    }
    return;
}
//读DS1302一个字节//
unsigned char outputbyte(void)
{
    unsigned char i;
    unsigned char ucdat=0;
    for(i=8; i>0; i--)
    {
        DS1302_IO=1;
        ucdat>>=1;
        if(DS1302_IO)ucdat|=0x80;
        DS1302_CLK=1;
        _nop_();
        DS1302_CLK=0;
    }
    return(ucdat);

}
//向DS1302某地址写一个字节数据//
void write_ds1302(unsigned char addr,unsigned char TDat)
{
    DS1302_RST=0;
    _nop_();
    DS1302_CLK=0;
    _nop_();
    DS1302_RST=1;
    InputByte(addr);
    _nop_();
    InputByte(TDat);
    DS1302_CLK=1;
    _nop_();
    DS1302_RST=0;
}
//读DS1302地址子程序//
unsigned char read_ds1302(unsigned char addr)
{
    unsigned char timedata;
    DS1302_RST=0;
    _nop_();
    DS1302_CLK=0;
    _nop_();
    DS1302_RST=1;
    InputByte(addr);
    timedata=outputbyte();
    DS1302_CLK=1;
    _nop_();
    DS1302_RST=0;
    return(timedata);
}
//DS1302的初始化//
void initial_ds1302()
{
    write_ds1302(0x8e,0x00);//写保护寄存器
    write_ds1302(0x8c,time[0]);//年
    write_ds1302(0x88,time[1]);//月
    write_ds1302(0x86,time[2]);//日
    write_ds1302(0x8A,time[3]);//星期
    write_ds1302(0x84,time[4]);//时
    write_ds1302(0x82,time[5]);//分
    write_ds1302(0x80,time[6]);//秒
    write_ds1302(0x8e,0x80);//写保护寄存器
}
//读DS1302时间//
void read_time()
{
    second=read_ds1302(0x81);
    minute=read_ds1302(0x83);
    hour=read_ds1302(0x85);
    week=read_ds1302(0x8B);
    day=read_ds1302(0x87);
    month=read_ds1302(0x89);
    year=read_ds1302(0x8d);

}

//液晶显示程序//
void write_com(uchar com)//写指令//
{
    lcdrs=0;
    lcdrw=0;
    P0=com;
    delay(5);
    lcden=1;
    delay(5);
    lcden=0;
}
void write_data(uchar date)   //写数据//
{
    lcdrs=1;
    lcdrw=0;
    P0=date;
    delay(5);
    lcden=1;
    delay(5);
    lcden=0;
}
void init()
{

    lcden=0;
    write_com(0x38);    //置初值//
    write_com(0x0c);
    write_com(0x06);
    write_com(0x81);
}
void Display(void)
{
    num=0;
    count=0;
    for(date=0; date<6; date++)
    {
        write_data(table3[date]);
    }
    //write_com(0x81);
    write_data(table[hour/16]);   //写第1行数据//
    write_data(table[hour%16]);
    write_data(':');

    write_data(table[minute/16]);
    write_data(table[minute%16]);
    write_data(':');

    write_data(table[second/16]);
    write_data(table[second%16]);
    //write_com(0x01);
    write_com(0x80+0x41);
    for(shi=0; shi<6; shi++)
    {
        write_data(table4[shi]);
    }
    write_data(table[year/16]);
    write_data(table[year%16]);
    write_data('-');
    write_data(table[month/16]);
    write_data(table[month%16]);
    write_data('-');
    write_data(table[day/16]);
    write_data(table[day%16]);

    write_com(0x80);
    for(count=0; count<16; count++);
    {
        write_data(table2[count]);
    }

}
/*------------------------------------------------
              判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
    DataPort= 0xFF;
    RS_CLR;
    RW_SET;
    EN_CLR;
    _nop_();
    EN_SET;
    return (bit)(DataPort & 0x80);
}
/*------------------------------------------------
              写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
    while(LCD_Check_Busy()); //忙则等待
    RS_CLR;
    RW_CLR;
    EN_SET;
    DataPort= com;
    _nop_();
    EN_CLR;
}
/*------------------------------------------------
              写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
    while(LCD_Check_Busy()); //忙则等待
    RS_SET;
    RW_CLR;
    EN_SET;
    DataPort= Data;
    _nop_();
    EN_CLR;
}

/*------------------------------------------------
                清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
    LCD_Write_Com(0x01);
    DelayMs(5);
}
/*------------------------------------------------
              写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
    if (y == 0)
    {
        LCD_Write_Com(0x80 + x);     //表示第一行
    }
    else
    {
        LCD_Write_Com(0xC0 + x);      //表示第二行
    }
    while (*s)
    {
        LCD_Write_Data( *s);
        s ++;
    }
}
/*------------------------------------------------
              写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
    if (y == 0)
    {
        LCD_Write_Com(0x80 + x);
    }
    else
    {
        LCD_Write_Com(0xC0 + x);
    }
    LCD_Write_Data( Data);
}
/*------------------------------------------------
             初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
    LCD_Write_Com(0x38);    /*显示模式设置*/
    DelayMs(5);
    LCD_Write_Com(0x38);
    DelayMs(5);
    LCD_Write_Com(0x38);
    DelayMs(5);
    LCD_Write_Com(0x38);
    LCD_Write_Com(0x08);    /*显示关闭*/
    LCD_Write_Com(0x01);    /*显示清屏*/
    LCD_Write_Com(0x06);    /*显示光标移动设置*/
    DelayMs(5);
    LCD_Write_Com(0x0C);    /*显示开及光标设置*/
}
void lcdxxmain(void)
{
    LCD_Write_Char(7,0,'0');
    LCD_Write_Char(8,0,'0');
    LCD_Write_String(1,1,"cumt j1b201");
}
void lcdshizhongmain(void)
{
    read_time();
    Display();

}
void main(void)
{
    int i,j;
    initial_ds1302();
    init();
    while(1)
    {
        for(i=0; i<100; i++)
        {
            lcdshizhongmain();
        }
        LCD_Init();
        LCD_Clear();//清屏
        for(j=0; j<10000; j++)
        {
            lcdxxmain();
        }
    }
}
