关于DS1302写进数据的一点小心得

本人是个新手,有不对的地方,希望能大神能指出来,写这个只是希望以后忘记的时候能回头过来看看。

先给代码,从书上看的。

 

#include<reg51.h>

sbit DS1302_SET = P1^5;
sbit DS1302_CK = P1^6;
sbit DS1302_IO = P1^7;

void DS1302ByteWrite(unsigned char dat)
{
    unsigned char mask;
    for (mask=0x01; mask!=0; mask<<=1) //低位在前,逐位移出
    {
        if ((mask&dat) != 0) //首先输出该位数据
        DS1302_IO = 1;
        else
        DS1302_IO = 0;
        DS1302_CK = 1; //然后拉高时钟
        DS1302_CK = 0; //再拉低时钟,完成一个位的操作
    }
    DS1302_IO = 1; //最后确保释放 IO 引脚
}

void DS1302_SingleWrite(unsigned char reg,unsigned char dat)
{
    DS1302_SET = 1;
    DS1302_ByteWrite(0x80|(reg<<1));
    DS1302_ByteWrite(dat);
    DS1302_SET = 0;
}

因为刚刚开始接触DS1302,没有实际的用到过DS1302的程序,所以我先自己按照书上写了下,融合自己的思想,结果根本得不到答案,无奈只好借书上源码,结果还是不得成功,我把自己的这部分的检验程序放在下面。

DS1302_SingleWrite(0,0x05);

我在主函数中添加了上面一段代码,想用protues实验一下是否能成功,结果半点反应都没,弄了许久没有思路,我只好求助万能的百度,看了很久都没弄懂,只要自己复制了网上的现在代码实验了一下,结果却成功了,下面是网上的代码。

#include <reg51.h>
#define uchar unsigned char 
#define uint unsigned int
sbit RST=P1^5;
sbit SCLK=P1^6;
sbit SDA=P1^7;


void DS1302WriteByte(uchar dat)

        uchar i; 
        SCLK=0;//初始时钟线置为0
        for(i=0;i<8;i++)//开始传输8个字节的数据
        { 
                SDA=dat&0x01;//取最低位,注意DS1302的数据和地址都是从最低位开始传输的
                SCLK=1;//时钟线拉高,制造上升沿,SDA的数据被传输
                SCLK=0;//时钟线拉低,为下一个上升沿做准备
                dat>>=1;//数据右移一位,准备传输下一位数据
        }
}

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_SET和DS1302_CK这两个IO口,查看代码原书后,发现作者在后面有个初始化函数Init_DS1302();,(不仔细看书吃得亏。。。),书上初始化函数如下。

 

void InitDS1302()
{
    unsigned char i;
    unsigned char code InitTime[] = { //2013 年 10 月 8 日 星期二 12:30:00
    0x00,0x30,0x12, 0x08, 0x10, 0x02, 0x13
    };
    DS1302_CE = 0; //初始化 DS1302 通信引脚
    DS1302_CK = 0;
    i = DS1302SingleRead(0); //读取秒寄存器
    if ((i & 0x80) != 0) //由秒寄存器最高位 CH 的值判断 DS1302 是否已停止
    {
        DS1302SingleWrite(7, 0x00); //撤销写保护以允许写入数据
        for (i=0; i<7; i++) //设置 DS1302 为默认的初始时间
        {
            DS1302SingleWrite(i, InitTime[i]);
        }  
    }
}

不过总算是弄懂了(有像我一样的新手的要记得初始化哦,加上DS1302_CE = 0; DS1302_CK = 0;),很好接着弄,看见这个初始函数的功能是我想要的(连续将字节写入DS1302的功能),这次我不敢瞎弄了(因为自己写的连续写程序一点作用也没,真伤心),把源码复制上去先试试,结果。。。。也出错了。逗我玩吗,原书上代码也能错?我第一反应就是马上看看是不是我写错了,但是我就写了一个初始函数上去,看着主函数里一条简简单单的InitDS1302()代码;我沉思了会,很无奈,还是改吧,结果改成了如下这样。

void DS1302_Init()
{

    unsigned char i;
    unsigned char InitTime[] = { //2013 年 10 月 8 日 星期二 12:30:00
    0x00,0x30,0x12, 0x08, 0x10, 0x02, 0x13
    };
    DS1302_SET = 0; //初始化 DS1302 通信引脚
    DS1302_CK = 0;
    DS1302_SingleWrite(7, 0x00); //撤销写保护以允许写入数据
    for (i=0; i<7; i++) //设置 DS1302 为默认的初始时间
    {
            DS1302_SingleWrite(i, InitTime[i]);
    }  

}

终于有了点反应,但是却不完全正确,例如就是时和秒发生了变化,分还是0,后来我觉得是不是DS1302需要反应时间,连续写它是不是反应不过来(大神勿笑,新手水平不够),因为写一个字节还是正常的,而写多个字节却发生了错误,而且还是时和秒之间的分没有数据,所以我才猜想是不是在主机写数据的时候,从机正在保存数据无法响应,等保存完后,主机已开始输出时的数据,好吧,加个延迟,结果。。。。连反应都没了。。。没办法,百度吧,百度DS1302连续写入数据,随便进了一网页,仔细看了写数据函数,发现了别人有EA=0;代码,仔细一想,赶紧把这条代码加了书中的源码中,运行,全部成功,\(^o^)/~!!

全文重点:记得    初始化(DS1302_CK=0;DS1302_SET=0;)  中断停止(EA=0)

希望能帮到其他同学。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值