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.

BQ40Z50 SMBS通讯

Other Parts Discussed in Thread: BQ40Z50

MCU和BQ40Z50采用IO模拟SMBS方式,进行通讯,访问RelativeStateOfCharge ()信息,发现返回的数据全是0xffff

代码如下


#define I2CDLY  10
#define I2C_WRADD   0x16
#define I2C_RDADD   0x17


void delayus(u16 us)
{
  for(u16 i=0;i<us;i++)
  {
    for(u8 j=0;j<100;j++);
  }

}

void I2C_Start()
{
  SET_SDAOut();  //设置SDA为输出
  SDA_H();
  delayus(I2CDLY);
  SCL_H();
  delayus(I2CDLY);
  SDA_L();
  delayus(I2CDLY);
}

void I2C_Stop()
{
  SET_SDAOut();
  SDA_L();
  delayus(I2CDLY);
  SCL_H();
  delayus(I2CDLY); 
  SDA_H();
  delayus(I2CDLY);
}

//主设备设置Nak信号,表示在接受数据时,主接收到数据Ng
void I2C_SetNak()  
{
  SET_SDAOut();
  SCL_L();
  delayus(I2CDLY);
  SDA_H();
  delayus(I2CDLY);
  SCL_H();
  delayus(I2CDLY);
}

//主设备设置Nak信号,表示在接受数据时,主接收到数据Ng
void I2C_SetAck()
{
  SET_SDAOut();
  SCL_L();
  delayus(I2CDLY);
  SDA_H();
  delayus(I2CDLY);
  SCL_H();
  delayus(I2CDLY);
}

 

//返回0,表示异常,返回1表示正常,=0,Nak,=1 ACK
u8 I2C_GetAck()
{
  u8 status =  0;
  SET_SDAIn();  ////设置SDA为输入,主机释放总线,
  delayus(I2CDLY);
  SCL_L();
  delayus(I2CDLY);
  SCL_H(); 
  if(SDA_InR==0) status=1;   //从设备接受到数据后,返回Ack信号,表示接受数据OK
  else status=0; //当返回数据为高时,或从设备未返回数据,则表示从设备接受数据NG
  delayus(I2CDLY);
  return(status);
}

void I2C_SendByte(u8 send_data)
{
  SET_SDAOut();
  for(u8 i=0;i<8;i++)
  {
   
    SCL_L();
    delayus(I2CDLY);
    if((send_data<<i)&0x80) SDA_H();
    else SDA_L();
    delayus(I2CDLY);
    SCL_H(); 
    delayus(I2CDLY);
  }
  SCL_L();
}


void I2C_GetByte(u8 *get_data)
{
  u8 i2cdata=0;
 
  SET_SDAIn();  //主机释放总线,

  for(u8 i=0;i<8;i++)
  {
    delayus(I2CDLY);
    SCL_L();
    delayus(I2CDLY);
    SCL_H(); 
    delayus(I2CDLY);
    i2cdata<<=1;
    if(SDA_InR) i2cdata +=1;
  }
  *get_data = i2cdata;
}


void BatterI2CInit()
{

  //以下采用IO口模拟I2C
  SET_SCLOut();  //slk out
  SET_SDAOut();  //SDA out
  SDA_H();      //SDA设置为H
  SCL_H();      //SCL设置为H
 
}


/*******************************************************************************
//returns the predicted remaining battery capacity as a percentage.
//读取相对剩余电量百分比%
*******************************************************************************/
u16 RelativeStateOfCharge()
{
  u8 tempdata[2];
  u16 relativecharge=0;
  I2C_Start();
  I2C_SendByte(I2C_WRADD);
  I2C_GetAck();
  I2C_SendByte(SBSCMD_GET_RL_CHARGE);
  I2C_GetAck();
 
  I2C_Start();
  I2C_SendByte(I2C_RDADD); 
  I2C_GetAck();
 
  I2C_GetByte(&tempdata[0]);
  I2C_SetAck();
  I2C_GetByte(&tempdata[1]);
  I2C_SetNak();
  I2C_Stop();
  relativecharge = tempdata[0];
  relativecharge = (relativecharge<<8)+tempdata[1];
 
  return(relativecharge);
}