DS18B20+DS1302+AT89S52+LCD12864万年历代码问题

2019-03-24 19:24发布

#include <reg52.h>
#include <intrins.h>
#include <string.h>
#define uint unsigned int
#define uchar unsigned char
typedef unsigned char BYTE;
sbit IO = P1^0;
sbit SCLK = P1^1;
sbit RST = P1^2;
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

uchar *WEEK[]={"SUN","***","MON","TUS","WEN","THU","FRI","SAT"};
uchar LCD_DSY_BUFFER1[]={"DATE 00-00-00    "};
uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00    "};
uchar DateTime[7];

void DelayMS(uint ms)
{
        uchar i;
        while(ms--)
        {
                 for(i=0;i<120;i++);
        }
}                   //DS1302片选口P1.2
                    //秒    分    时    日    月  星期    年
BYTE code init[] = {0x00, 0x00, 0x20, 0x01, 0x01, 0x05, 0x10};
BYTE data now[7];

void DS1302_Initial();
void DS1302_SetTime(BYTE *p);
void DS1302_GetTime(BYTE *p);

/*void main()
{
    DS1302_Initial();               //初始化DS1302
    DS1302_SetTime(init);           //设置初始时间

    DS1302_GetTime(now);            //读取当前时间
    while (1);
}*/

/**************************************
延时X微秒(STC12C5A60S2@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void Delay()
{
    _nop_();
    _nop_();
}
/**************************************
从DS1302读1字节数据
**************************************/
BYTE DS1302_ReadByte()
{
    BYTE i;
    BYTE dat = 0;

    for (i=0; i<8; i++)             //8位计数器
    {
                SCLK = 0;                   //时钟线拉低
                Delay();                //延时等待
        dat >>= 1;                        //数据右移一位
                if (IO) dat |= 0x80;        //读取数据
                SCLK = 1;                   //时钟线拉高
                Delay();                //延时等待
        }

    return dat;
}

/**************************************
向DS1302写1字节数据
**************************************/
void DS1302_WriteByte(BYTE dat)
{
    char i;
    for (i=0; i<8; i++)             //8位计数器
    {
        SCLK = 0;                   //时钟线拉低
        Delay();                //延时等待
        dat >>= 1;                  //移出数据
        IO = CY;                    //送出到端口
        SCLK = 1;                   //时钟线拉高
        Delay();                //延时等待
    }
}
/**************************************
读DS1302某地址的的数据
**************************************/
BYTE DS1302_ReadData(BYTE addr)
{
    BYTE dat;
    RST = 0;
    Delay();
    SCLK = 0;
    Delay();
    RST = 1;
    Delay();
    DS1302_WriteByte(addr);         //写地址
    dat = DS1302_ReadByte();        //读数据
    SCLK = 1;
    RST = 0;
    return dat;
}
/**************************************
往DS1302的某个地址写入数据
**************************************/
void DS1302_WriteData(BYTE addr, BYTE dat)
{
    RST = 0;
    Delay();
    SCLK = 0;
    Delay();
    RST = 1;
    Delay();
    DS1302_WriteByte(addr);         //写地址
    DS1302_WriteByte(dat);          //写数据
    SCLK = 1;
    RST = 0;
}
/**************************************
写入初始时间
**************************************/
void DS1302_SetTime(BYTE *p)
{
    BYTE addr = 0x80;
    BYTE n = 7;
    DS1302_WriteData(0x8e, 0x00);   //允许写操作
    while (n--)
    {
        DS1302_WriteData(addr, *p++);
        addr += 2;
    }
    DS1302_WriteData(0x8e, 0x80);   //写保护
}
/**************************************
读取当前时间
**************************************/
void DS1302_GetTime(BYTE *p)
{
    BYTE addr = 0x81;
    BYTE n = 7;
    while (n--)
    {
        *p++ = DS1302_ReadData(addr);
        addr += 2;
    }
}
/**************************************
初始化DS1302
**************************************/
void DS1302_Initial()
{
    RST = 0;
    SCLK = 0;
    DS1302_WriteData(0x8e, 0x00);   //允许写操作
    DS1302_WriteData(0x80, 0x00);   //时钟启动
    DS1302_WriteData(0x90, 0xa6);   //一个二极管+4K电阻充电
    DS1302_WriteData(0x8e, 0x80);   //写保护
}

uchar Read_LCD_State()
{
        uchar state;
        RS=0;RW=1;EN=1;DelayMS(1);
        state=P0;
        EN = 0;DelayMS(1);
        return state;
}


void LCD_Busy_Wait()
{
        while((Read_LCD_State()&0x80)==0x80);
        DelayMS(5);
}

void Write_LCD_Data(uchar dat)
{
        LCD_Busy_Wait();
        RS=1;RW=0;EN=0;P0=dat;EN=1;DelayMS(1);EN=0;       
}

void Write_LCD_Command(uchar cmd)
{
        LCD_Busy_Wait();
        RS=0;RW=0;EN=0;P0=cmd;EN=1;DelayMS(1);EN=0;       
}

void Init_LCD()
{
        Write_LCD_Command(0x38);
        DelayMS(1);       
        Write_LCD_Command(0x01);
        DelayMS(1);       
        Write_LCD_Command(0x06);
        DelayMS(1);       
        Write_LCD_Command(0x0c);
        DelayMS(1);       
}

void Set_LCD_POS(uchar p)
{
        Write_LCD_Command(p|0x80);       
}

void Display_LCD_String(uchar p,uchar *s)
{
        uchar i;
        Set_LCD_POS(p);
        for(i=0;i<16;i++)
        {
                Write_LCD_Data(s);
                DelayMS(1);        
        }
}

void Format_DateTime(uchar d,uchar *a)
{
        a[0]=d/10+'0';
        a[1]=d%10+'0';
}

void main()
{
        Init_LCD();
        while(1)
        {
                 DS1302_GetTime(now);
                Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);
                Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);
                Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);

                strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);

                Format_DateTime(DateTime[2],LCD_DSY_BUFFER1+5);
                Format_DateTime(DateTime[1],LCD_DSY_BUFFER1+8);
                Format_DateTime(DateTime[0],LCD_DSY_BUFFER1+11);

                Display_LCD_String(0x00,LCD_DSY_BUFFER1);
                Display_LCD_String(0x40,LCD_DSY_BUFFER2);
        }
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。