请问硬件上做什么处理好,软件上是不是要多读几次,然后做平滑处理呢!
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.
用示波器卡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显示电量,求指导一下!
其实这里面最重要的是需要理解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?