找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5075|回复: 13
收起左侧

DS1302读取时间一直显示65:65:65

[复制链接]
ID:452950 发表于 2020-3-3 17:55 | 显示全部楼层 |阅读模式
这两天在做51单片机考勤系统需要显示时间,就用DS1302来做时钟,本来都已经能正常显示和改时间了,不知道出了什么问题,上电后年月日时分秒都显示65:65:65了,换了一个DS1302也是这样,请问什么情况会导致这样,谢谢大家!我用的代码贴在下面,但是之前本来是能显示的,今天突然出的问题,接线也没有变过,应该不是代码的问题。。。


#include <reg52.h
#include <intrins.h>
#include "ds1302.h"

//设置时间,time[0]-time[6]数据存放顺序为:秒,分,时,日,月,星期,年
unsigned char times[7]={00,30,23,12,6,6,10};
sbit SCLK=P0^3;
sbit IO=P0^2;
sbit RST=P0^1;

sbit ACC7=ACC^7;
sbit ACC0=ACC^0;

/*================================================================*/
/*                        向1302当前地址处写入1字节数据                      */
/*================================================================*/
void write_1302_byte(unsigned char d)
{
    unsigned char i;
    ACC=d;              //将8位数据写入ACC
    for(i=8;i>0;i--)    //循环8次将ACC8位数据从低位到高位写入1302
    {   
        IO=ACC0;            //将ACC的最低位转送到IO口
        SCLK=1;         //上升沿写入1位数据
        SCLK=0;
        ACC=ACC>>1;            //将ACC次低位变为最低位
    }
}
/*=================================================================*/

/*=================================================================*/
/*                    从1302的当前地址处读出1字节数据                           */
/*=================================================================*/
unsigned char read_1302_byte(void)
{
    unsigned char i;
    for(i=8;i>0;i--)
    {
        ACC=ACC>>1;
        ACC7=IO;
        SCLK=1; //时钟下降沿读1位数据
        SCLK=0;

    }
               

    return (ACC);
}
/*=================================================================*/

/*================================================================*/
/*                        将数据Data写入1302寄存器add处                      */
/*================================================================*/
void write_1302_reg(unsigned char add,unsigned char d)
{
    RST= 0;
    SCLK=0;
    RST= 1;
    write_1302_byte(add);        //将1302的指针移到add处
    write_1302_byte(d);            //往add处写入数据
    SCLK=1;
    RST=0;              //停止写数据
}
/*=================================================================*/

/*==================================================================*/
/*                            读寄存器add处的值                                */
/*==================================================================*/
unsigned char read_1302_reg(unsigned char add)
{
    unsigned char d;
    RST=0;
    SCLK=0;
    RST=1;
    write_1302_byte(add);
    d=read_1302_byte();
    SCLK=1;
    RST=0;
    return (d);
}
/*=================================================================*/

/*===========================================================================================*/
/*                    设置时间,time[0]-time[6]数据存放顺序为:秒,分,时,日,月,星期,年                     */
/*===========================================================================================*/
void write_1302_time(unsigned char *time)
{
    unsigned char add=0x80;            //地址add初值(秒),偶数地址为只写
    unsigned char i;
    unsigned char timeBCD[7];   //用以存放time数据的BCD码值
    bdata unsigned char l,h;         //单位变量,分别存放时间数据(8421BCD码)的低4位和高4位
    for(i=0;i<7;i++)            //将时间数据转为BCD码放入timeBCD中
    {
        l=time[i]%10;
        h=time[i]/10;
        timeBCD[i]=h*16+l;
    }   
    write_1302_reg(0x8e,0x00);            //禁止写
    for(i=0;i<7;i++)
    {
        write_1302_reg(add,timeBCD[i]); //将时间数据写入1302对应的寄存器
        add+=2;                         //地址移动,确保地址为偶数
    }
    write_1302_reg(0x8e,0x80);          //允许写
}
/*===========================================================================================*/

/*=================================================================================================*/
/*                                                读取当前时间                                               */
/*=================================================================================================*/
void read_1302_time(unsigned char time[])
{
    unsigned char i;
    unsigned char add=0x81;         //设置地址add初值(秒),奇数为只读
    bdata unsigned char l,h;             //单位变量,分别存放时间数据(8421BCD码)的低4位和高4位,用以进行十进制转换
        write_1302_reg(0x8e,0x00);  //禁止写
    for(i=0;i<7;i++)
    {
        time[i]=read_1302_reg(add);        //将时间数据(8421BCD码)从1302对应的寄存器中读出
        l=time[i]&0x0f;                //l存放time的低4位,即个位
        h=(time[i]>>4)&0x0f;    //h存放time的高4位,即十位
        time[i]=h*10+l;         //时间数据以十进制形式放进time[i]中
        add+=2;                        //地址移动,确保地址为奇数
    }
}





回复

使用道具 举报

ID:190577 发表于 2020-3-3 20:39 | 显示全部楼层
时钟可以走时?
回复

使用道具 举报

ID:452950 发表于 2020-3-3 22:12 | 显示全部楼层

没有反应,一直显示65,读不出时间
回复

使用道具 举报

ID:462827 发表于 2020-3-4 00:18 | 显示全部楼层
主函数呢,换引脚试了吗
回复

使用道具 举报

ID:648281 发表于 2020-3-4 07:49 | 显示全部楼层
你好!
你的意思是以前都是正常可以使用的?
回复

使用道具 举报

ID:452950 发表于 2020-3-4 10:05 | 显示全部楼层
51hei**1140 发表于 2020-3-4 07:49
你好!
你的意思是以前都是正常可以使用的?

对的,前一天都能显示,我设置的没有实时更新,只读一瞬间的时间,但是现在也读不出来了。现在考虑换一种时钟芯片了
这个是读时间然后显示的程序,只能读出65年65月65日65:65:65
void Puttime(void)
{
    read_1302_time(times);
       
        WriteCommand(0x81);

    WriteData(((times[6]%100)/10)+48);
    WriteData((times[6]%10)+48);   
        PutStr(0,2,"年");   
    WriteData(((times[4]%100)/10)+48);
    WriteData((times[4]%10)+48);   
        PutStr(0,4,"月");
    WriteData(((times[3]%100)/10)+48);
    WriteData((times[3]%10)+48);
        PutStr(0,6,"日");
        WriteCommand(0x92);                //90

    WriteData(((times[2]%100)/10)+48);
    WriteData((times[2]%10)+48);   
        WriteData(':');   
    WriteData(((times[1]%100)/10)+48);
    WriteData((times[1]%10)+48);   
        WriteData(':');
    WriteData(((times[0]%100)/10)+48);
    WriteData((times[0]%10)+48);
}      
回复

使用道具 举报

ID:648281 发表于 2020-3-4 10:20 | 显示全部楼层
xxpp2011 发表于 2020-3-4 10:05
对的,前一天都能显示,我设置的没有实时更新,只读一瞬间的时间,但是现在也读不出来了。现在考虑换一种 ...

你这个主要应该是程序的问题;
DS1302 丝印写的都有什么字?
回复

使用道具 举报

ID:452950 发表于 2020-3-4 11:21 | 显示全部楼层
51hei**1140 发表于 2020-3-4 10:20
你这个主要应该是程序的问题;
DS1302 丝印写的都有什么字?

DS1302
1705C2
+163AN
回复

使用道具 举报

ID:452950 发表于 2020-3-4 18:37 | 显示全部楼层
hantu 发表于 2020-3-4 00:18
主函数呢,换引脚试了吗

重新定义了三个空置的引脚,但是还是不行,用万用表测线路都是通的,有可能是晶振坏了,我买了个新的等到货了再试试。。
回复

使用道具 举报

ID:496117 发表于 2020-3-4 19:02 | 显示全部楼层
h*16+l; // 这个是错误的,16进制跟10进制只是显示的不一样,内部值是一样的,不用你手动处理
回复

使用道具 举报

ID:46065 发表于 2020-3-4 22:01 | 显示全部楼层
你3个上拉电阻加了没?我以前也有过这种情况!
回复

使用道具 举报

ID:452950 发表于 2020-3-5 11:52 | 显示全部楼层
wxxl 发表于 2020-3-4 22:01
你3个上拉电阻加了没?我以前也有过这种情况!

谢谢,可能确实是这个原因,我接了以前焊的时钟电路可以正常工作,之前用的是独立的时钟模块,上面三个信号引脚没有接上拉电阻,我还以为不是必须接的。。。
回复

使用道具 举报

ID:1096001 发表于 2023-11-11 23:39 | 显示全部楼层
读数据时要把指令改为读指令
回复

使用道具 举报

ID:1085441 发表于 2023-11-12 22:43 | 显示全部楼层
只有SDIO引脚必须要上拉电阻,一般10k,其它2根线只有设置成准双向IO口就行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表