hu9jj 发表于 2021-4-12 14:19

【CuriosityNano测评报告】09.模拟I2C驱动DS1307日历模块

#申请原创#

    之前曾经在帖子中提过驱动DS1307日历模块时读出的数据不正确,当时以为是模拟I2C的时序问题,花费了3~4天时间反复调试都没有结果,只好先测试长短按键及滚轮编码器。今天再继续测试驱动DS1307日历模块,仔细分析代码及逻辑分析仪抓取的时序图,发现初始化DS1307设置日期时间的时候数据就不正确,从时序图上可以看出写入的并不是正确的数据,如下图所示:


    读出的数据时序图与写入的基本一致(见下图),说明读数据基本正确,是写数据有问题:


    于是进一步分析模拟I2C的写入函数,代码如下:
/******************************************************************************************************************************************
* 函数名称: I2C_Send()
* 功能说明:        向IIC总线发送一个字节的数据
* 输    入: byte dat         要发送的数据
* 输    出: 无
******************************************************************************************************************************************/
void SI2C_Send(uint8_t dat)
{
    uint8_t i;
    SDA_OUT();
    SCL_0();                              //拉低时钟开始数据传输
    for(i=0;i<8;i++)
    {
      if(((dat&0x80)>>7) == 1)
            SDA_1();                        //准备好SDA数据
      else
            SDA_0();
      dat<<=1;
<blockquote>      DELAY_microseconds(2);

    上述代码若有问题,则可能是这行if(((dat&0x80)>>7) == 1),
    经过反复测试,发现这行代码并无问题,能正确判断,但优化成下面这样也行:
if(dat&0x80)
    SDA_1();   //准备好SDA数据
                else
    SDA_0();
                dat<<=1;

    代码优化后依旧写数据不正确,于是便想起之前测试LCD显示时遇到的数组指针传递不过去的问题,我原来是通过数组指针将要写入的日期时间数据存入在数组中,通过指针传递到模拟I2C的写函数中,代码如下:
      SI2C_8bitBuffWrite(DS1307_ADDR,0,8,DS_Buff);

    模拟I2C写入函数接收相关的参数:
    uint8_t SI2C_8bitBuffWrite(uint8_t I2Caddr,uint8_t addr,uint8_t size,uint8_t *buff)

    分析问题应该是出在此处,于是便修改为通过全局变量数组来传递,测试果然不出所料,能够正确地写入和读出数据了。下面是模拟I2C写入的代码:
/**********************************************************************************************
* 函数名称: SI2C_8bitBuffWrite()
* 功能说明: 向I2C器件的地址addr开始写入size个字节的数据,将要写入的数据存储在全局变量数组I2C_Buff中
* 输    入: uint8_t addr      数据被写入从addr开始的地址处
*                        uint8_t size      要设置的数据个数(1~8)
* 输    出: uint8_t                0= 成功1=出现错误
**********************************************************************************************/
uint8_t SI2C_8bitBuffWrite(uint8_t I2Caddr,uint8_t addr,uint8_t size,uint8_t *buff)
{
    uint8_t i = 0;
      
    SI2C_Start();               //产生起始信号
    SI2C_Send(I2Caddr|0);   //发送从设备芯片地址及读写位,0表示写
    if(SI2CIsAck())               //检测从设备是否有响应
    {
      SI2C_Stop();            //产生停止信号
      return 1;
    }

    SI2C_Send(addr);         //发送数据要写入的地址
    if(SI2CIsAck())                //检测从设备是否有响应
    {
      SI2C_Stop();            //产生停止信号
      return 2;
    }

    for(i=0;i<size;i++)
    {
//      SI2C_Send(buff);
      SI2C_Send(DS_Buff);
      if(SI2CIsAck())         //检测从设备是否有响应
      {
            SI2C_Stop();         //产生停止信号
            return 3;
      }
    }

    SI2C_Stop();                  //产生停止信号

    return 0;
}

    这是测试过程的照片,用逻辑分析仪来抓取I2C的时序:


    调试过程:


    这是视频动画:

dql2015 发表于 2021-4-13 17:08

这个逻辑分析仪不错,有链接吗

hu9jj 发表于 2021-4-13 18:04

dql2015 发表于 2021-4-13 17:08
这个逻辑分析仪不错,有链接吗

2016年淘宝上买的,待会我找找看。

单片小菜 发表于 2021-4-13 22:41

不错呀,感谢楼主的分享,不错的资料。

guijial511 发表于 2021-4-14 07:03

学习了,感谢楼主的分享。

kkzz 发表于 2021-5-3 13:36

ds1307时钟芯片中文资料

hudi008 发表于 2021-5-3 13:37

DS1302和DS1307有什么区别

lzmm 发表于 2021-5-3 13:38

ds1302和ds1307相比,哪一个计时更准确一些?

minzisc 发表于 2021-5-3 13:38

性能怎么样   

selongli 发表于 2021-5-3 13:38

               

fentianyou 发表于 2021-5-3 13:39

驱动DS1307需要多大的周期

xiaoyaodz 发表于 2021-5-3 13:39

怎么做内部的授时呢   

pixhw 发表于 2021-5-3 13:39

需要上拉电阻吗   

sdlls 发表于 2021-5-3 13:39

数据格式有问题吗   

febgxu 发表于 2021-5-3 13:40

这个有硬件iic吗   

hu9jj 发表于 2021-5-3 17:53

febgxu 发表于 2021-5-3 13:40
这个有硬件iic吗

有硬件I2C,但我一直没有调试成功。

tfqi 发表于 2021-5-11 13:43

运行稳定吗?

wiba 发表于 2021-5-11 13:43

看来调试并不是一帆风顺啊

zljiu 发表于 2021-5-11 13:56

是什么导致读出的数据不正确呢

coshi 发表于 2021-5-11 13:56

仿真效果还是不错的
页: [1] 2
查看完整版本: 【CuriosityNano测评报告】09.模拟I2C驱动DS1307日历模块