TI中文支持网
TI专业的中文技术问题搜集分享网站

bq24195 I2C通信不上

急急急!!!这两天我用430g2452的USI模块的I2C模式来跟bq24195进行通信,读取bq24195的时候读取回来的数据都是0xff,我怀疑我自己写的读取代码有问题然后我就查看了一下读取时序,发现发送每一字节数据之后等待从机回应ACK的过程中SCL是高电平状态(空闲状态),正常情况下不是被从机拉低的么?这是软件问题还是硬件上存在问题呢。一下我把I2C配置代码贴出,请大家帮忙一下….

void I2c_Master_2452(void) //配置I2C模块
{
USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup
USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt
USICKCTL = USIDIV_3+USISSEL_2+USICKPL; // Setup USI clocks: SCL = SMCLK/8 (~125kHz)
USICNT |= USIIFGCC; // Disable automatic clear control
USICTL0 &= ~USISWRST; // Enable USI
USICTL1 &= ~USIIFG; // Clear pending flag
}

这个配置是TI官网上的例程。

下面是我中断服务程序里面读取寄存器的代码

{
switch(I2C_State)
{
case 0: // Generate Start Condition & send address to slave
USISRL = 0x00; // set MSB of the shiftregister to 0
USICTL0 |= USIGE+USIOE; //置位USIGE、USIOE
USICTL0 &= ~USIGE; //清除USIGE
USISRL = 0X0D6; // … and transmit address, R/W = 0
USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
I2C_State = 2; // Go to next state: receive address (N)Ack
break;

case 2: // Receive Address Ack/Nack bit
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
I2C_State = 4; // Go to next state: check (N)Ack
break;

case 4: // Process Address Ack/Nack & handle data TX
USICTL0 |= USIOE; // SDA = output
if (USISRL & 0x01) // If Nack received…
{ // Send stop…
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 18; // Go to next state: generate Stop
}
else
{ // Ack received, TX data to slave…
USISRL = RegAddr; // 发送要访问的寄存器地址
USICNT |= 0x08; // Bit counter = 8, start TX
I2C_State = 6; // Go to next state: receive data (N)Ack
}
break;
case 6: // Receive Address Ack/Nack bit
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
I2C_State = 8; // Go to next state: check (N)Ack
break;

case 8: // Process Address Ack/Nack & handle data TX
USICTL0 |= USIOE; // SDA = output
if (USISRL & 0x01) // If Nack received…
{ // Send stop…
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 18; // Go to next state: generate Stop
}
else
{ // 产生开始条件并发送从机地址
// Delay_1ms(1);
USISRL = 0x00; // set MSB of the shiftregister to 0
USICTL0 |= USIGE+USIOE; //置位USIGE、USIOE
USICTL0 &= ~USIGE; //清除USIGE
USISRL = 0x0D7; // … and transmit address, R/W = 0
USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address
I2C_State = 10; // Go to next state: receive address (N)Ack
}
break;

case 10: // Receive Data Ack/Nack bit
USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
I2C_State = 12; // Go to next state: check (N)Ack
break;

case 12: // Process Data Ack/Nack & send Stop
USICTL0 |= USIOE;
if (USISRL & 0x01) // If Nack received…
{ // Send stop…
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 18; // Go to next state: generate Stop
}
else // Ack received
{ //接收bq24195数据 USICTL0 &= ~USIOE; // SDA = input
USICNT |= 0x08; // Bit counter = 1, receive (N)Ack bit
I2C_State = 14; // Go to next state: check (N)Ack
}
break;
case 14: // Process bq24195发来的数据 and Transmit Data Nack bit
ReadData = USISRL;
USISRL = 0x01;
USICTL0 |= USIOE; // SDA = output
USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit
I2C_State = 16; // Go to next state: check (N)Ack
break;
case 16://Send Stop …
USISRL = 0x00;
USICNT |= 0x01; // Bit counter = 1, SCL high, SDA low
I2C_State = 18; // Go to next state: generate Stop
break;
case 18: // Generate Stop Condition USISRL = 0x0FF; // USISRL = 1 to release SDA
USICTL0 |= USIGE; // Transparent latch enabled
USICTL0 &= ~(USIGE+USIOE);// Latch/SDA output disabled
I2C_State = 0; // Reset state machine for next transmission
LPM0_EXIT; // Exit active for next transfer break;
}

USICTL1 &= ~USIIFG; // Clear pending flag
}

Jason Shen:

1.无MCU控制的情况下,我们的charger也是可以使用默认状态充电的,请检查默认状态下,芯片的工作正常与否。

2.使用测试程序,只对一个寄存器写,看是否有效果,比如只对设置充电电流的那个寄存器写操作。

3.注意I2C地址,可以用示波器抓波形看时序是否正常。

Mingmo Zhu:

感觉I2C地址最大嫌疑,你用D6(Hex)试下?

另外,ACK的表现是:第9个时钟脉冲时SCL为高、SDA为低。

rong luan wei:

回复 Mingmo Zhu:

我查看时序的时候发现第八个时钟之后(也就是发送完一个字节之后)SCL的电平状态是高电平(空闲状态),而且第八个时钟跟第九个时钟是有一段时间间隔的,等待ACK的时候:SCL时钟线是高电平状态,SDA线的扎un国泰是保持最后的状态。正常情况下等待ACK的时候SCL时钟线不是被从机拉低吗?

George Luo1:

回复 rong luan wei:

楼主,你现在可以对BQ24195进行写操作么?先尝试一下写操作,看看BQ24195的工作状态会不会改变。如果写操作可以,只是读操作不行的话,你查一下你的时序里面有没有重复启动位。如果写操作也不行,你按照楼上所述,核对一下器件地址是否写对了。

Andy Kwong:

我也遇到相同問題!

到ADDRESS 應該是送D6 的才對吧. 因為SPEC 寫是先送MSB, 而地址是7BIT, 最後一BIT 是方向, 所以WRITE 應該是送D6, READ 是送D7

但我這樣寫之後, 到發送REG ADDR 就讀不到ACK了..老是讀回HIGH

rong luan wei:

回复 Jason Shen:

charger是默认充电正常的,说明芯片正常;I2C地址也都对了,现在能够实现读写了,但是我用示波器抓到的时序还是:等待ACK的过程中scl是空闲状态

rong luan wei:

回复 Mingmo Zhu:

第九个时钟脉冲之后SCL不应该是低电平的吗?这么会是高电平呢?

rong luan wei:

回复 George Luo1:

已经读写正常了,地址没错,但是还是不明白为什么第九个时钟之后SCL会是空闲状态(高电平),正常的I2C时序不是等待ACK的时候SCL被拉低的吗?

Jason Shen:

回复 rong luan wei:

你是不是发了stop位?

可以上传下SDA与SCL的波形。

George Luo1:

回复 rong luan wei:

问一下,首先,你的第九个时钟之后SCL空闲,是每一个字节第九个时钟过后都会空闲么?这个肯定是I2C配置出了问题。看一下你是否误发了停止位。

赞(0)
未经允许不得转载:TI中文支持网 » bq24195 I2C通信不上
分享到: 更多 (0)