时钟芯片问题,请各位大神解答

2019-07-15 13:53发布

我想让单片机断电后,时间计数不停止。比如我关掉单片机时候数码管显示时间为12-05-48(12点05分48秒),过了12秒钟,再打开单片机,时间显示为12-06-00(12点06分00秒)。以下为代码,如果想实现上面功能,哪里需要改动,大神指教。

//时钟芯片
#include<reg51.h>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

sbit DSIO=P3^4;
sbit RST=P3^5;
sbit SCLK=P3^6;

void Ds1302Write(uchar addr, uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302Readtime();

extern uchar TIME[7];


//--定义使用的IO--//
#define GPIO_DIG P0

//--声明全局变量--//
void DigDisplay();

//--定义全局变量--//
unsigned char code DIG_CODE[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码
unsigned char table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned char DisplayData[8];
//用来存放要显示的8位数的值


uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13};



void Ds1302Write(uchar addr, uchar dat)
{
        uchar n;
        RST = 0;
        _nop_();

        SCLK = 0;//先将SCLK置低电平。
        _nop_();
        RST = 1; //然后将RST(CE)置高电平。
        _nop_();

        for (n=0; n<8; n++)//开始传送八位地址命令
        {
                DSIO = addr & 0x01;//数据从低位开始传送
                addr >>= 1;
                SCLK = 1;//数据在上升沿时,DS1302读取数据
                _nop_();
                SCLK = 0;
                _nop_();
        }
        for (n=0; n<8; n++)//写入8位数据
        {
                DSIO = dat & 0x01;
                dat >>= 1;
                SCLK = 1;//数据在上升沿时,DS1302读取数据
                _nop_();
                SCLK = 0;
                _nop_();       
        }       
                 
        RST = 0;//传送数据结束
        _nop_();
}


uchar Ds1302Read(uchar addr)
{
        uchar n,dat,dat1;
        RST = 0;
        _nop_();

        SCLK = 0;//先将SCLK置低电平。
        _nop_();
        RST = 1;//然后将RST(CE)置高电平。
        _nop_();

        for(n=0; n<8; n++)//开始传送八位地址命令
        {
                DSIO = addr & 0x01;//数据从低位开始传送
                addr >>= 1;
                SCLK = 1;//数据在上升沿时,DS1302读取数据
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }
        _nop_();
        for(n=0; n<8; n++)//读取8位数据
        {
                dat1 = DSIO;//从最低位开始接收
                dat = (dat>>1) | (dat1<<7);
                SCLK = 1;
                _nop_();
                SCLK = 0;//DS1302下降沿时,放置数据
                _nop_();
        }

        RST = 0;
        _nop_();        //以下为DS1302复位的稳定时间,必须的。
        SCLK = 1;
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        return dat;       
}


void Ds1302Init()
{
        uchar n;
        Ds1302Write(0x8E,0X00);                 //禁止写保护,就是关闭写保护功能
        for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年
        {               
                Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);       
        }
        Ds1302Write(0x8E,0x80);                 //打开写保护功能
}



void Ds1302ReadTime()
{
        uchar n;
        for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年
        {
                TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
        }
               
}

void main()
{
        Ds1302Init();
        while(1)
        {       
                Ds1302ReadTime();
                DisplayData[0] = DIG_CODE[TIME[2]/16];                                //时
                DisplayData[1] = DIG_CODE[TIME[2]&0x0f];                                 
                DisplayData[2] = 0x40;
                DisplayData[3] = DIG_CODE[TIME[1]/16];                                //分
                DisplayData[4] = DIG_CODE[TIME[1]&0x0f];       
                DisplayData[5] = 0x40;
                DisplayData[6] = DIG_CODE[TIME[0]/16];                                //秒
                DisplayData[7] = DIG_CODE[TIME[0]&0x0f];
                DigDisplay();       
        }
       
}


void DigDisplay()
{
        unsigned char i;
        unsigned int j;
        for(i=0;i<8;i++)
        {
                P1=table1[i];
                GPIO_DIG=DisplayData[i];//发送段码
                j=50;                                                 //扫描间隔时间设定
                while(j--);       
                GPIO_DIG=0x00;//消隐
        }
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。