用430的io口软件模拟iic读取bq27541为什么有时候数据还是会出现ffff?
请问硬件上做什么处理好,软件上是不是要多读几次,然后做平滑处理呢!
我前几天也遇到过这样的问题,时序没错,但是有时候读出来数据不对,坐等高手解答
每条读取的指令后增加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,所谓的释放总线就是将总线拉高吗?
