关于DS1302的读数据时序

2019-03-24 19:01发布

   遇到一个奇怪的事情,开发板上的读取DS1302的时序与datasheet上的不一致,却能正常读写;我按照我的理解改写后,确不能读写。具体如下:    1.  该图是DS1302的读时序,可以看到数据是下降沿后输出。也就是在SCLK下降沿后,I/O上输出串行数据,该数据需要单片机对其接收。对于这种方式,用一种不太恰当的说法就是“10D10D10D......”,其中1、0表示SCLK的输出,D表示单片机接收数据    2.  开发板上的程序如下:        Write_Ds1302_Byte(address);   //写入“读”控制命令
     for (i=0;i<8;i++)   //循环8次 读取数据
       {  
        if(SDA)
            temp|=0x80;   //每次传输低字节
        SCK=0;
        temp>>=1;   //右移一位
        SCK=1;
        _nop_();
       }
        同样用上述表达方式,这个程序的流程是“D01D01D01......”,这显然是与datasheet上的说法不同。    3.  用2的程序,可以正常读写;若把它的流程改为与datasheet一致,即“10D10D......”,显示却不能正常读写。        改程序只需改for循环内部,改后如下:            SCK=0;        //上一个函数已将SCK给1,故给0即产生下降沿  
        if(SDA)
            temp|=0x80;   //每次传输低字节
         temp>>=1;   //右移一位
         SCK=1;
        _nop_();
  是我理解错了,还是datasheet上的图有误?求指教!   此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
14条回答
bvcbvc
2019-03-26 18:36
楼主提供的开发板程序 我 的和你一样。我认为 读数据时是这样的:
1.刚开始的SDA会被8次移位移出去,对结果无影响。
2.第一次产生的下降沿所释放的数据被下一次for循环给捕捉,共进行了7次有效捕捉。
3.在for循环结束后应该加上语句:if(SDA)
            temp|=0x80; 对1302的最高位进行捕获。
4.程序不修改能正常运行 我认为是:每次移位最高位被0代替,1302的各时间寄存器最高位内部永远达不到1,因为59对应01011001(BCD)。阴差阳错。
以上是我的见解。请指正。
改正的程序:
for (i=0;i<8;i++)                 //循环8次 读取数据
        {        
                if(SDA)            //注意到第一次sda的数据是随机的,最终会被8次移位移出去  
                temp|=0x80;                        //每次传输低字节
                temp>>=1;       
                SCK=1;
                _nop_();
                _nop_();                                //此处才开始产生下降沿,产生的数据会在下一次循环中被接受
                SCK=0;                                                               
                _nop_();
           _nop_();                        //右移一位
       
        }
        if(SDA)temp|=0x80;    // 对最后释放的数据 进行采集

[ 本帖最后由 bvcbvc 于 2012-8-14 20:40 编辑 ]

一周热门 更多>