用DS1302做时钟时仿真出现问题了,时间隔好几秒才走一下

2020-02-05 08:54发布

#include<reg51.h>
#include<intrins.h>
#include "delay.h"
#include "1602.h"
#include "DS1302.h"
unsigned char table_time1[]="2012-07-04  3";                                 //外部变量,DS1302中用到
unsigned char table_time2[]="8:23:00";                                                //同上
unsigned char table3[]="i love xxx";                //调试用
main()
{
        unsigned char i;
        init_1602();
        init_DS1302();                          //设定DS1302的初始时间
        while(1)
        {
                read_time();                                                           //DS130的读取时间函数
                /*for(i=0;i<13;i++)
                        display_1602(1,i+2,table_time1[0]);
                for(i=0;i<7;i++)
                        display_1602(2,i+6,table_time1[0]);*/
                for(i=0;i<10;i++)
                        display_1602(1,i,table3[i]);                        //1602的显示函数 第一行第i列显示数据table3[i]
        }
               
}
问题就是仿真的时候给ds1302设定时间了,但是它不按照1秒1秒的走,而是走的很慢,好几秒才走一次
但是如果我把1602的显示函数给注释的时候,芯片又能正常的走了
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
23条回答
yangkuan85988
1楼-- · 2020-02-05 09:23
 精彩回答 2  元偷偷看……
yangkuan85988
2楼-- · 2020-02-05 14:38
本帖最后由 yangkuan85988 于 2012-7-4 11:30 编辑

void write_byte_DS1302(unsigned char dat)
{
        unsigned char i;
        for(i=0;i<8;i++)
        {
                SCL_DS1302=0;
                IO_DS1302=dat&0X01;
                dat>>=1;
                SCL_DS1302=1;
                _nop_();
        }       
}
unsigned char read_byte_DS1302()
{
        unsigned char i,temp;
        for(i=0;i<8;i++)
        {
                SCL_DS1302=0;
                temp>>=1;
                temp=IO_DS1302;
                SCL_DS1302=1;                       
        }
        return temp;
}

void write_DS1302(unsigned char command,unsigned char date)
{
        RST_DS1302=0;
        _nop_();
        SCL_DS1302=0;
        _nop_();
        IO_DS1302=1;
        _nop_();
        RST_DS1302=1;
        _nop_();
        write_byte_DS1302(command);
        write_byte_DS1302(date);
        RST_DS1302=0;
        _nop_();
}
unsigned char read_DS1302(unsigned char command)
{
        unsigned char temp1,temp2,temp;
        RST_DS1302=0;
        _nop_();
        RST_DS1302=1;
        _nop_();
        SCL_DS1302=0;
        _nop_();
        IO_DS1302=1;
        _nop_();

        write_byte_DS1302(command);
        temp1=read_byte_DS1302();
        RST_DS1302=0;
        _nop_();
        temp2=temp1/16;
        temp1=temp1%16;                                //数据格式转换
        temp=temp2*10+temp1;
       
        return temp;                               
}
void init_DS1302()
{
        RST_DS1302=0;
        write_DS1302(PROTECT,0X00);                                //去除写保护
        write_DS1302(WRITE_YEAR,0X12);                        //初始化年                 2012年
        write_DS1302(WRITE_WEEK,0X03);                        //初始化星期        星期三
        write_DS1302(WRITE_MONTH,0X07);                        //初始化月                7月
        write_DS1302(WRITE_DAY,0X04);                        //初始化天                4号
        write_DS1302(WRITE_HOUR,0X08);                        //初始化小时        8点
        write_DS1302(WRITE_MINUTE,0X17);                //初始化分钟        17分
        write_DS1302(WRITE_SECOND,0X00);                //初始化秒钟        0秒
        write_DS1302(PROTECT,0X80);                                //写保护
}
void read_time()
{
        unsigned char second,minute,hour,week,day,month,year;
        write_DS1302(PROTECT,0X00);                                //去除写保护
        year  =read_DS1302(READ_YEAR);                       
        month =read_DS1302(READ_MONTH);
        day   =read_DS1302(READ_DAY);
        week  =read_DS1302(READ_WEEK);
        hour  =read_DS1302(READ_HOUR);
        minute=read_DS1302(READ_MINUTE);
        second=read_DS1302(READ_SECOND);
        write_DS1302(PROTECT,0X80);                                //写保护

        table_time1[2]=year/10;
        table_time1[3]=year%10;
        table_time1[5]=month/10;
        table_time1[6]=month%10;
        table_time1[8]=day/10;
        table_time1[9]=day%10;
        table_time1[13]=week;
       
        table_time2[0]=hour/10;
        table_time2[1]=hour%10;
        table_time2[3]=minute/10;
        table_time2[4]=minute%10;
        table_time2[6]=second/10;
        table_time2[7]=second%10;
}       
ytx1689567
3楼-- · 2020-02-05 17:04
给SDA端接上拉试试,
BXAK
4楼-- · 2020-02-05 22:52
要显示秒位最好至少0.5s更新一次秒位数据,而你的超级循环里面执行周期太长(大于0.5s了,你的1602显示程序里是不是用了Delay延时……等等),无法及时更新,
用状态机吧,如果不熟悉状态机就开个定时器中断约0.5s更新一次时间将就将就
zpxa001
5楼-- · 2020-02-06 01:06
芯片本身走时应该是正确的,问题出在你的软件上,读取时间->显示时间可能有问题。一般情况下,要显示秒的变化,理论上来讲最少应在小于1s的时间间隔里读取秒数据,当然时间间隔小一些秒显示的精度会更高(即显示的时间与芯片时间的误差会更小)。
yangkuan85988
6楼-- · 2020-02-06 03:06
 精彩回答 2  元偷偷看……

一周热门 更多>