微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 硬件电路设计 > TI电源管理交流 > 单片机模拟IIC时序读取BQ34Z100的电压不正常。

单片机模拟IIC时序读取BQ34Z100的电压不正常。

时间:10-02 整理:3721RD 点击:

我发送读取命令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相应的产品文件夹下看一下。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top