单片机模拟IIC时序读取BQ34Z100的电压不正常。
我发送读取命令0x08,返回的值是两个字节的0xFF,0xFF。这个值应该是不正确的。
请教TI的FAE。先谢过了~
1)这样的问题可能出在哪里
2)程序我是参考BQ27421 MSP430的模拟IIC代码, 里面I2CDELAY是多少us了
下面是我的波形。
下面是我写的代码(参考BQ27421 MSP430的模拟IIC代码)
void MSP430_SWI2CMST_start(void)
{
SDA_1; // SDA = 1
I2CDELAY; // Quick delay
SCL_1; // SCL = 1
I2CDELAY; // Quick delay
SDA_0; // SDA = 0
I2CDELAY; // Quick delay
SCL_0; // SCL = 0
I2CDELAY; // Quick delay
}
void MSP430_SWI2CMST_stop(void)
{
SDA_0; // SDA = 0
I2CDELAY; // Quick delay
SCL_1; // SCL = 1
I2CDELAY; // Quick delay
SDA_1; // SDA = 1
I2CDELAY; // Quick delay
}
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 & 0x80) // 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 change1
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 stretchingchange2
GPIO_SDA_SetDirection(0);
I2CDELAY; // Quick delay
ack = I2CReadSDA(); // Read ACK state from Slave
GPIO_SDA_SetDirection(1);
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
GPIO_SDA_SetDirection(0);
while (bits > 0) // Loop until all bits are read
{
SCL_1; // SCL = 1
// while ((PxIN & SCL) == 0); // Wait for any SCL clock stretchingchange3
I2CDELAY; // Quick delay
data = (data << 1); // Shift bits 1 place to the left
if (I2CReadSDA()) // 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
}
GPIO_SDA_SetDirection(1);
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
}
void MSP430_SWI2CMST_writeBlock(unsigned char SlaveAddress,
unsigned int numBytes, unsigned char multi,
void* TxData)
{
unsigned int i;
unsigned char *temp;
temp = (unsigned char *)TxData; // Initialize array pointer
MSP430_SWI2CMST_start(); // Send Start condition
MSP430_SWI2CMST_txByte(0xaa); // [ADDR] + R/W bit = 0
for (i = 0; i < numBytes; i++)
{
MSP430_SWI2CMST_txByte(*(temp)); // Send data and ack
temp++; // Increment pointer to next element
}
if (multi == 0) // Need STOP condition?
{
MSP430_SWI2CMST_stop(); // Yes, send STOP condition
}
I2CDELAY; // Quick delay
}
void MSP430_SWI2CMST_readBlock(unsigned char SlaveAddress,
unsigned int numBytes, void* RxData)
{
unsigned int i;
unsigned char* temp;
temp = (unsigned char *)RxData; // Initialize array pointer
MSP430_SWI2CMST_start(); // Send Start condition
MSP430_SWI2CMST_txByte(0xab); // [ADDR] + R/W bit = 1
for (i = 0; i < numBytes; i++)
{
if (i == (numBytes - 1))
*(temp) = MSP430_SWI2CMST_rxByte(NACK);// Read last 8-bit data with no ACK
else
*(temp) = MSP430_SWI2CMST_rxByte(ACK);// Read 8-bit data & then send ACK
temp++; // Increment pointer to next element
}
MSP430_SWI2CMST_stop(); // Send Stop condition
}
void bq34z100_read(unsigned char cmd, unsigned int bytes)
{
unsigned char tx[1];
tx[0] = cmd;
MSP430_SWI2CMST_writeBlock(I2CSLAVEADDR, 1, 1, tx);
delay_us(100);
MSP430_SWI2CMST_readBlock(I2CSLAVEADDR, bytes, RxData);
}
发送完
MSP430_SWI2CMST_writeBlock(I2CSLAVEADDR, 1, 1, tx);
这条指令后,会发送一个STOP状态,
把这个MSP430_SWI2CMST_stop(); // Send Stop condition
删除再尝试。
另外,I2C应该MSP430有示例代码,可以在MSP430相应的产品文件夹下看一下。