This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

用430的io口软件模拟iic读取bq27541为什么有时候数据还是会出现ffff?

Other Parts Discussed in Thread: BQ3050

     请问硬件上做什么处理好,软件上是不是要多读几次,然后做平滑处理呢!

  • 我前几天也遇到过这样的问题,时序没错,但是有时候读出来数据不对,坐等高手解答

  • 每条读取的指令后增加2ms的等待时间。

    i2C的时钟周期不超过100KHz

  •  

     

     

     

    谢谢王工, 我最近一直在测试BQ3050的稳定性测试,把我数据读取后用上位机写到excel,经过一个星期的数据对比,发现数据还是会掉,所以我想请问一下,是不是只要按照EV2300的时序来进行读写就一定保证稳定了,软件上是否需要进行一定的处理呢!

  • 假设我是bq3050的话,我是不是在发0x17之之后延迟2ms再去读?

  • 谢谢王工,我再试试!

  • 用示波器卡EV2300的波形,发现SCL周期是16us,也就是说iic的通讯速率是64khz左右,并没有规格书上所说的100khz, 而且ti读取一个电压数据差不多用了1ms,

  • 现在不会出现0XFFFF了,但是数据好像有错误,假设我电压数据,有时候读出来既不是ffff也不是正常的电压数据,是不是bq芯片数据没有更新啊!我现在把iic速率提高到64khz 了!

  • 请大家重视这个问题啊,如果是想用MCU做一些与电量计通讯的项目的话,这个问题肯定会遇到,大家有什么好的建议可以说出来啊

     

    我这个以前读错的数据就是0xfff,现在读错的数据是其他莫名其妙的数据,所以我想这里面肯定有东西值得去研究!

  • 感谢ti,现在读取不会出错了,确实是我时序的问题,关键是读字节和写字节,一定要按照ti给的历程去操作,  关键的地方在于几个while

    贴出关键的读字节和写字节

    unsigned char MSP430_SWI2CMST_txByte(unsigned char data)
    {
    unsigned char bits, temp, ack;

    SCL_0; // SCL = 0
    temp = data; // Initialize temp variable
    bits = 0x08; // Load I2C bit counter
    while (bits != 0x00) // Loop until all bits are shifted
    {
    if (temp & BIT7) // Test data bit
    SDA_1; // SDA = 1
    else
    SDA_0; // SDA = 0
    I2CDELAY; // Quick delay
    SCL_1; // SCL = 1
    while ((PxIN & SCL) == 0); // Wait for any SCL clock stretching
    I2CDELAY; // Quick delay
    temp = (temp << 1); // Shift bits 1 place to the left
    SCL_0; // SCL = 0
    bits = (bits - 1); // Loop until 8 bits are sent
    }
    I2CDELAY;
    SDA_1; // SDA = 1
    SCL_1; // SCL = 1
    while ((PxIN & SCL) == 0); // Wait for any SCL clock stretching
    I2CDELAY; // Quick delay
    ack = (PxIN & SDA); // Read ACK state from Slave
    SCL_0; // SCL = 0
    if (ack) // Return ACK state to calling app
    return (1);
    else
    return (0);
    }

    unsigned char MSP430_SWI2CMST_rxByte(char ack)
    {
    unsigned char bits, data = 0;

    SDA_1; // SDA = 1
    bits = 0x08; // Load I2C bit counter
    while (bits > 0) // Loop until all bits are read
    {
    SCL_1; // SCL = 1
    while ((PxIN & SCL) == 0); // Wait for any SCL clock stretching
    I2CDELAY; // Quick delay
    data = (data << 1); // Shift bits 1 place to the left
    if (PxIN & SDA) // Check digital input
    data = (data + 1); // If input is high, store a '1'
    SCL_0; // SCL = 0
    I2CDELAY; // Quick delay
    bits = (bits - 1); // Decrement I2C bit counter
    }
    if (ack) // Need to send ACK to Slave?
    SDA_0; // Yes, so pull SDA low
    else
    SDA_1; // No, so keep SDA high
    SCL_1; // SCL = 1
    I2CDELAY; // Equivalent to sending N(ACK)
    SCL_0; // SCL = 0
    SDA_1; // SDA = 1

    return (data); // Return 8-bit data byte
    }

  • 感谢您的贡献.

  • 兄弟,最后问题解决了吗?最近也在做同样的工作,是否可以共享一下资料,先谢过了,我的QQ:1013511649,目前我的要求是通过AVR MCU的i2c接口读取gas gauge的电量信息并通过几个LED显示电量,求指导一下!

  • 兄弟,解决了吗?我也想知道IIC哪儿有问题?

  • 兄弟 I2C delay 是多少ms? 能否告知  我现在IO 模拟IIc  能读出数据 但是有时 也会出错  

  • 我也遇到这问题,您最后是怎么解决的呢

  • 其实这里面最重要的是需要理解I2C的协议里面的clock stretch机制。因为电量计芯片本身也是一个MCU,它也需要处理很多的任务,所以在收到一个通讯的指令的时候,也许它并不能够马上就响应,这种时候,芯片会把CLK拉低一段时间,然后才进行响应。那么主机这边如果发现CLK被拉住了,bus busy,那么就应该等待slave设备释放了总线之后再继续发送后面的时钟脉冲,特别是芯片进入了sleep模式的时候。这里的重点在于主机需要检测总线是否忙,而不是一个固定的延时来进行读取。

  • 抛开这个电量计芯片本身不谈,现在是一个msp430单片机实时的将外置的一个数据采集器的数据保存在片上RAM中,430单片机在IIC协议中作为从机存在,采用中断方式和主机进行通信,然后只预留出IIC的scl和sda两个接口,我设计IIC的主机来读取从机430中片上RAM所暂存的数据,那么间歇性无规律的出现全FF的数据也是由于始终延展吗?要是因为是始终延展,如您所说需要判断总线是否忙,在只预留出SCL和SDA两条接口的情况下,如何判断 bus busy?

  • 检测是否SCL,在主机释放的状态下,是否一直是低,增加timeout 恢复机制

  • 1,主机是STM32,电量计作为从机的情况下,电量计作为从机能将SCL拉低吗?还是SCL只能是主机STM32进行控制?

    2,所谓的释放总线就是将总线拉高吗?