proteus仿真ds1302显示99秒的问题

我用proteus仿真ds1302用数码管显示时间时,发现秒显示不对,是每99秒清零一次,但是ds1302旁边的小窗口显示是对的,不知是哪里的问题,希望大侠们能指导小弟一下。

#include <at89x52.h>
#define uchar unsigned char
#define uint unsigned int
sbit RST=P1^0;
sbit SCLK=P1^1;
sbit SDA=P1^2;
/************************************************
*功能:写入8bit数据
*调用:delayus()
*输入:dat:要写入的数据
*输出:无
*************************************************/
void DS1302WriteByte(uchar dat)
{
uchar i;
SCLK=0;//初始时钟线置为0
//delay_us(2);
for(i=0;i<8;i++)//开始传输8个字节的数据
{
SDA=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
//delay_us(2);
SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输
//delay_us(2);
SCLK=0;//时钟线拉低,为下一个上升沿做准备
dat>>=1;//数据右移一位,准备传输下一位数据
}
}
/************************************************
*功能:读取8bit的数据
*调用:delayus()
*输入:无
*输出:dat:读取的数据
*************************************************/
uchar DS1302ReadByte()
{
uchar i,dat;
//delay_us(2);
for(i=0;i<8;i++)
{
dat>>=1;//要返回的数据左移一位
if(SDA==1)//当数据线为高时,证明该位数据为1
dat|=0x80;//要传输数据的当前值置为1,若不是,则为0
SCLK=1;//拉高时钟线
//delay_us(2);
SCLK=0;//制造下降沿
//delay_us(2);
}
return dat;//返回读取出的数据
}
/************************************************
*说明:先写地址,后读数据
*功能:从cmd相应地址中读取一个字节的数据
*调用:DS1302WriteByte(),DS1302ReadByte()
*输入:cmd:要写入的控制字节
*输出:dat:读取的数据
*************************************************/
uchar DS1302Read(uchar cmd)
{
uchar dat;
RST=0;//初始CE线置为0
SCLK=0;//初始时钟线置为0
RST=1;//初始CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要读取的时间/日历地址
dat=DS1302ReadByte();//读取要得到的时间/日期
SCLK=1;//时钟线拉高
RST=0;//读取结束,CE置为0,结束数据的传输
return dat;//返回得到的时间/日期
}
/************************************************
*说明:先写地址,后写数据
*功能:向cmd相应地址中写一个字节的数据
*调用:DS1302WriteByte()
*输入:cmd:要写入的控制字,dat:要写入的数据
*************************************************/
void DS1302Write(uchar cmd,uchar dat)
{
RST=0;//初始CE线置为0
SCLK=0;//初始时钟线置为0
RST=1;//初始CE置为1,传输开始
DS1302WriteByte(cmd);//传输命令字,要写入的时间/日历地址
DS1302WriteByte(dat);//写入要修改的时间/日期
SCLK=1;//时钟线拉高
RST=0;//读取结束,CE置为0,结束数据的传输
}

要用DS1302计时,就是按时钟计时,怎么可能会有99秒哪,谁家的钟能走出99秒来,这肯定是错误的。
如果不用DS1302,用单片机定时,而且是当秒表用,可以计出99秒。追问

是的,开始用单片机定时做的电子钟,是正常的,用DS1302后出现这个问题,麻烦大侠方便的话,帮忙找一下原因,多谢了。由于字数限制,无法把剩余的程序传上来。

追答

主要原因就是DS1302的读写程序有问题,而且仿真程序和在实物上运行的程序也是有区别的,就是说,你仿真可以正常显示时间了,可到了实物上就会出现错误,这是因为仿真和实物在时序上有区别,而DS1302要求的时序又比较严格。
//时钟驱动程序,用于仿真图,因字数限制,注释内容只好删掉了。这些程序作为参考。
//引脚定义根据仿真图重新定义

sbit SRST=P2^1; //定义5脚

sbit S_IO=P2^3; //定义6脚
sbit SCLK=P2^2; //定义7脚
unsigned char idata cdate[]={0x00,0x30,0x16,0x20,0x08,4,0x15,0};//定义1302时钟,日期初始值

//****DS1302读一个字节函数****/
unsigned char readbyte()
{
unsigned char i,wordb=0;
S_IO=1;
for(i=8;i>0;i--)
{
SCLK=0;
nop;
wordb>>=1;
if(S_IO) wordb|=0x80;
SCLK=1;
nop;
}
return wordb;
}
//****DS1302写一个字节函数****//

void writebyte(unsigned char wordb)
{
unsigned char i;
for(i=8;i>0;i--)
{
SCLK=0;
nop;
wordb>>=1;
S_IO=CY;
SCLK=1;
nop;
}
}
//设置时钟计时的初始时间和日期

void writetime()
{
unsigned char i;
SCLK=0;
nop;
nop;
SRST=1;
writebyte(0xbe);
for(i=0;i<8;i++)
writebyte(cdate[i]);
SRST=0;
}
//****读DS1302内部时钟,只读3个字节,读出的时钟放入时间数组cdate[]中****//
void readclock()

{
unsigned char i;
SCLK=0;
SRST=1;
writebyte(0xbf);
S_IO=1;
for(i=0;i<3;i++) //i<3,只读出时钟,不读日期,读日期时,i<8读全部数据
cdate[i]=readbyte();
SRST=0;
}

温馨提示:内容为网友见解,仅供参考
无其他回答
相似回答