微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 时钟芯片问题,请各位大神解答

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

时间:10-02 整理:3721RD 点击:
我想让单片机断电后,时间计数不停止。比如我关掉单片机时候数码管显示时间为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;//消隐
        }
}

我用 DS1302 时候外接入电池后掉电会不停计数的。

掉电检测,数据手册有说。另外要有电池供应

学习这个程序   感觉单片有些困难呀

我用数码管显示  为什么不会  

有电池供应啊 没有电池供应 单片机数码管上怎么可能还显示相应程序

什么困难 是单片机不可靠么 还是单片机b格太低

小编误解了  我是说我对单片程序这一块不懂

单片机加多个时钟芯片吧,想DS1302就可以做到你想要的了。网上一堆资料,学会自个看看

那应该用什么来学习

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top