DS1302时钟芯片读出的时间与实时时间不一致,这是什么原因?

时间:2022-03-16 16:37:36
使用DS1302时钟芯片,用LED点阵显示屏显示时间,但是设置好初始时间后,显示时间是没问题的,就是显示的时间比实际时间慢很多,而且相差越来越大,这到底是怎么回事啊?求解答!

9 个解决方案

#1


该回复于2012-05-09 16:53:41被版主删除

#2


接晶振了吗?要不就是LED点阵刷新费时太多,但如果相差越来越大说明程序有问题!

#3


引用 2 楼  的回复:
接晶振了吗?要不就是LED点阵刷新费时太多,但如果相差越来越大说明程序有问题!


应该跟LED点阵刷新没关系的,他们之间没有必然关系,我只是隔段时间把时间读出来显示而已。我还是先用示波器看一下晶振。。。

#4


读时间不要太频繁!

#5


如果晶振没有问题,很有可能是对时钟芯片操作不当引起的,如楼上:读时间太频繁!

#6


引用 4 楼  的回复:
读时间不要太频繁!


我把读时间改长后读,还是一样,比实际时间慢很多。。。

#7


现在正常了,晶振频率不对,用示波器看了下,不是32.768KHZ,居然是3.3768KHZ,换了个晶振就好了。还有确实是,如果读时间太频繁,显示好像更不上来显示。。。

#8


我是不知道怎么写这个程序,,头都是大的。

#9


引用 8 楼  的回复:
我是不知道怎么写这个程序,,头都是大的。

 

#include<STC12C5A32S2.h> 
//位寻址寄存器定义
sbit  ACC_0 = ACC^0;
sbit  ACC_7 = ACC^7;

//管脚定义
sbit  DS1302_CLK = P1^1;              //实时时钟时钟线引脚 
sbit  DS1302_IO  = P1^2;              //实时时钟数据线引脚 
sbit  DS1302_RST = P1^3;              //实时时钟复位线引脚

#if 1
void DS1302WriteByte(uchar dat) //实时时钟写入一字节(内部函数)

    uchar i;

    ACC = dat;
    for(i=8; i>0; i--)
    {
        DS1302_IO = ACC_0;      //相当于汇编中的 RRC
        DS1302_CLK = 1;
        DS1302_CLK = 0;
        ACC >>= 1; 
    } 
}

uchar DS1302ReadByte()         //实时时钟读取一字节(内部函数)

    uchar i,dat1=0,dat2=0;

    for(i=8; i>0; i--)
    {
        ACC >>= 1;             //相当于汇编中的 RRC 
        ACC_7 = DS1302_IO;
        DS1302_CLK = 1;
        DS1302_CLK = 0;
    }
   dat1 = ACC;
   dat2 = dat1>>4;    //数据进制转换
   dat1 = dat1%16;    //十六进制转十进制
   dat1 = dat1+dat2*10; 
   return(dat1); 
}

void Write1302(uchar cmd, uchar dat) //cmd: DS1302地址命令, dat: 要写的数据
{
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302WriteByte(cmd);        // 地址,命令 
    DS1302WriteByte(dat);        // 写1Byte数据
    DS1302_RST = 0;
    DS1302_CLK = 1;


uchar Read1302(uchar cmd)        //读取DS1302某地址的数据
{
    uchar dat=0;

    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302WriteByte(cmd);          //地址,命令 
    dat = DS1302ReadByte();        //读1Byte数据
    DS1302_RST = 0;
    DS1302_CLK = 1;

    return(dat);
}
#endif

#1


该回复于2012-05-09 16:53:41被版主删除

#2


接晶振了吗?要不就是LED点阵刷新费时太多,但如果相差越来越大说明程序有问题!

#3


引用 2 楼  的回复:
接晶振了吗?要不就是LED点阵刷新费时太多,但如果相差越来越大说明程序有问题!


应该跟LED点阵刷新没关系的,他们之间没有必然关系,我只是隔段时间把时间读出来显示而已。我还是先用示波器看一下晶振。。。

#4


读时间不要太频繁!

#5


如果晶振没有问题,很有可能是对时钟芯片操作不当引起的,如楼上:读时间太频繁!

#6


引用 4 楼  的回复:
读时间不要太频繁!


我把读时间改长后读,还是一样,比实际时间慢很多。。。

#7


现在正常了,晶振频率不对,用示波器看了下,不是32.768KHZ,居然是3.3768KHZ,换了个晶振就好了。还有确实是,如果读时间太频繁,显示好像更不上来显示。。。

#8


我是不知道怎么写这个程序,,头都是大的。

#9


引用 8 楼  的回复:
我是不知道怎么写这个程序,,头都是大的。

 

#include<STC12C5A32S2.h> 
//位寻址寄存器定义
sbit  ACC_0 = ACC^0;
sbit  ACC_7 = ACC^7;

//管脚定义
sbit  DS1302_CLK = P1^1;              //实时时钟时钟线引脚 
sbit  DS1302_IO  = P1^2;              //实时时钟数据线引脚 
sbit  DS1302_RST = P1^3;              //实时时钟复位线引脚

#if 1
void DS1302WriteByte(uchar dat) //实时时钟写入一字节(内部函数)

    uchar i;

    ACC = dat;
    for(i=8; i>0; i--)
    {
        DS1302_IO = ACC_0;      //相当于汇编中的 RRC
        DS1302_CLK = 1;
        DS1302_CLK = 0;
        ACC >>= 1; 
    } 
}

uchar DS1302ReadByte()         //实时时钟读取一字节(内部函数)

    uchar i,dat1=0,dat2=0;

    for(i=8; i>0; i--)
    {
        ACC >>= 1;             //相当于汇编中的 RRC 
        ACC_7 = DS1302_IO;
        DS1302_CLK = 1;
        DS1302_CLK = 0;
    }
   dat1 = ACC;
   dat2 = dat1>>4;    //数据进制转换
   dat1 = dat1%16;    //十六进制转十进制
   dat1 = dat1+dat2*10; 
   return(dat1); 
}

void Write1302(uchar cmd, uchar dat) //cmd: DS1302地址命令, dat: 要写的数据
{
    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302WriteByte(cmd);        // 地址,命令 
    DS1302WriteByte(dat);        // 写1Byte数据
    DS1302_RST = 0;
    DS1302_CLK = 1;


uchar Read1302(uchar cmd)        //读取DS1302某地址的数据
{
    uchar dat=0;

    DS1302_RST = 0;
    DS1302_CLK = 0;
    DS1302_RST = 1;
    DS1302WriteByte(cmd);          //地址,命令 
    dat = DS1302ReadByte();        //读1Byte数据
    DS1302_RST = 0;
    DS1302_CLK = 1;

    return(dat);
}
#endif