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.

BQ27520电量计IIC读取失败

bq27520  STM32L433 iic读取失败

1.电路设计部分

2.程序读取

参考sluua35.pdf文档,读取器件类型
Example using DEVICE_ TYPE subcommand:
●To device address 0xAA, starting at command 0x00, write two bytes of data: 0x01 and 0x00.
●Then read the response using an incremental read. To device address 0xAB, starting at command
0x00, read two bytes.
读取代码
void  bq27520 read type (u8 * buf)
    u8 temp;
    IIC Start() ;
    IIC Send Byte (0xAA) ;
    IIC wait Ack() ;
    IIC Send Byte (0x00) ;
    IIC Wait Ack() ;
    IIC Send Byte (0x01) ;
    IIC wait Ack() ;
    IIC Send Byte (0x00) ;
    IIC Wait Ack() ;
    IIC stop() ;
    HAL Delay(2) ;
    IIC start() ;
    IIC_ Send Byte (0xAA) ;
    IIC Wait Ack() ;
    IIC Send Byte (0x00) ;
    IIC Wait Ack() ;
    IIC start() ;
    IIC Send Byte (0xAB) ;
    IIC wait Ack() ;
    buf[0]=IIC Read Byte(1) ;
    buf[1]=IIC Read Byte(0) ;
    IIC stop() ;
}
3.逻辑分析仪抓取波形

  • 您好,单片机通讯您可以参考下面的文档。

    www.ti.com.cn/.../slua467b.pdf

  • 您好,地址是响应了,但是感觉对寄存器或指令的读写操作均应答异常,目前有以下疑问:

    1.根据手册进行操作,目前只有地址或个别寄存器回应应答信号,是不是需要通过什么配置才可以生效访问寄存器?

    2.手册中提到需要配置0x61寄存器00,寄存器有响应,但是写00时应答失败

    3.参照这个流程也是不行

    4.测试相关代码如下

    void Bq_delay_us(uint32_t us)
    {
    	uint32_t i = us;
    	uint8_t j = 0;
    
    	for(i = 0; i < us; i++)
      {
        //__NOP();
        j=5;  
        while(j--);    
      }
    }
    
    void BQ_SDA_IOMODE(uint8_t _mode)
    {
      GPIO_InitTypeDef  GPIO_InitStructure={0}; 
      
      //SDA
      GPIO_InitStructure.Pin   = BQ_SDA_PIN;
      GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
      GPIO_InitStructure.Pull    = GPIO_NOPULL;
      if(_mode == 0)
        GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_OD;
      else
        GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
      
      HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);  
    }
    
    void BQ_I2C_Start(void)
    {
      BQ_SDA_IOMODE(0);   //0=输出,1=输入
    
      BQ_I2C_SDA_H();     //数据线高
      BQ_I2C_SCL_H();     //时钟线高
      Bq_delay_us(2);
      BQ_I2C_SDA_L();     //数据线从高跳变到低
      Bq_delay_us(2);
      BQ_I2C_SCL_L();     //时钟线低
    }
    
    void BQ_I2C_End(void)
    {
      BQ_SDA_IOMODE(0);   //0=输出,1=输入
      
      BQ_I2C_SCL_L();     //时钟线低
      BQ_I2C_SDA_L();     //数据线低
      Bq_delay_us(2);
      BQ_I2C_SCL_H();     //时钟线高
      __NOP();
      BQ_I2C_SDA_H();     //数据线正跳变
      Bq_delay_us(2);
    }
    
    void BQ_I2C_SendACK(uint8_t _ack)
    {
      BQ_I2C_SCL_L();
      BQ_SDA_IOMODE(0);   //0=输出,1=输入
      if(_ack == TRUE)
        BQ_I2C_SDA_L();   //应答ack:scl高电平期间,数据线低
      else
        BQ_I2C_SDA_H();   //不用应答nak:scl高电平期间,数据线高
      
      BQ_I2C_SCL_H();
      Bq_delay_us(2);
      BQ_I2C_SCL_L();
      Bq_delay_us(2);
    }
    
    bool BQ_I2C_RecvWait_ACK(void)
    {
      uint16_t i = 0;
      u8 t;
    	
    	BQ_SDA_IOMODE(1);           //0=输出,1=输入
      BQ_I2C_SDA_H();             //
      Bq_delay_us(2);
      BQ_I2C_SCL_H();             //拉高时钟线
      Bq_delay_us(2);
    
      while(BQ_I2C_SDA_STATU())   //等待从机应答信号
      {
        i++;
        if(i > 250)
        {
    			BQ_I2C_End();
    			//Log_Print("i2c wait ack outtime\r\n");
    			return 1;
        }
      }
    
      BQ_I2C_SCL_L();             //拉低时钟线
    	Bq_delay_us(2);
    
    	return 0;
    }
    
    uint8_t BQ_I2C_ReadByte(u8 ack)
    {
    	u8 i,receive=0;
      BQ_SDA_IOMODE(1);           //0=输出,1=输入
    
    	for(i=0;i<8;i++)
    	{
    		BQ_I2C_SCL_L();           //拉低时钟线
    		Bq_delay_us(2);
    		BQ_I2C_SCL_H();           //拉高时钟线
    		receive<<=1;
    		if(BQ_I2C_SDA_STATU())
    			receive++;
    		Bq_delay_us(2);
    	}
    
      BQ_I2C_SendACK(ack);
    
      return receive;
    }
    
    void BQ_I2C_WriteByte(uint8_t _c)
    {
    	u8 t;
    	uint8_t txdata = _c;
    
    	BQ_SDA_IOMODE(0);          //0=输出,1=输入
    	BQ_I2C_SCL_L();
    
    	for(t=0;t<8;t++)
    	{
    		if((txdata&0x80)>>7)
    			BQ_I2C_SDA_H();
    		else
    			BQ_I2C_SDA_L();
    		txdata<<=1;
    
    		BQ_I2C_SCL_H();
    		Bq_delay_us(2);
    		BQ_I2C_SCL_L();
    		Bq_delay_us(2);
    	}
    }
    
    /* common routines for bq I2C gauge */
    static int bq_read_i2c_word(uint8_t reg)
    {
    	uint8_t data[2] = {0};
    	int ret;
      uint8_t i;
    
    	BQ_I2C_Start();
    	BQ_I2C_WriteByte((BQ277520_ADDRESS<<1)|0); //发送器件地址+写命令
    	if(BQ_I2C_RecvWait_ACK())                  //等待应答
    	{
    		BQ_I2C_End();
    		return 1;
    	}
    	BQ_I2C_WriteByte(reg);                     //写寄存器地址
    	BQ_I2C_RecvWait_ACK();                     //等待应答
     
    	BQ_I2C_Start();
    	BQ_I2C_WriteByte((BQ277520_ADDRESS<<1)|1); //发送器件地址+读命令
    	if(BQ_I2C_RecvWait_ACK())                  //等待应答
    	{
    		BQ_I2C_End();
    		return 1;
    	}
    
    	data[0] = BQ_I2C_ReadByte(1);              //读数据,发送ACK
    	data[1] = BQ_I2C_ReadByte(0);				  	   //读数据,发送NACK
    
    	BQ_I2C_End();//产生一个停止条件
    	
    	return ret;
    }
    
    bool bq_write_i2c_word(uint8_t reg, uint16_t value)
    {
    	uint8_t data[2] = {0};
    
    	data[0] = (uint8_t)(value);
      data[1] = (uint8_t)(value>>8);
    
    	BQ_I2C_Start();
    	BQ_I2C_WriteByte((BQ277520_ADDRESS<<1)|0);   //发送器件地址+写命令
    	if(BQ_I2C_RecvWait_ACK())                    //等待应答
    	{
    		BQ_I2C_End();
    		return 1;
    	}
    	BQ_I2C_WriteByte(reg);                       //写寄存器地址
    	BQ_I2C_RecvWait_ACK();                       //等待应答
    
    	BQ_I2C_WriteByte(data[0]);                   //发送数据
    	BQ_I2C_RecvWait_ACK();                       //等待ACK
    
    	BQ_I2C_WriteByte(data[1]);                   //发送数据
    	BQ_I2C_RecvWait_ACK();                       //等待ACK
    	BQ_I2C_End();
    
      return 0;
    }
    
    static int bq27520_read_fw_version(void)
    {
    	int ret = 0;
    	//uint8_t databuf[2] = {0};
    
    	ret = bq_write_i2c_word(BQ27520_REG_CONTRL, BQ27520_SUBCMD_DFVER);
    	Bq_delay_us(1000);	
    	ret = bq_read_i2c_word(BQ27520_REG_CONTRL);
    
    
    	return ret;
    }
    
    

  • 您好,您可以用EV2300只读取一个数,如电池电压,然后用示波器把i2c的波形抓取下来。再抓一下自己软件编写的的i2c波形,同样读取这个电压,看看两者有什么区别,很快就能定位到问题。比如ACK信号有没有?发送地址对不对?发送命令时序对不对等。
  • 您好,目前驱动OK了,可以读取的电压,但是如何配置Bq27520,读取电量呢?您是否可以提供一下指导,比如参看那份数据手册等?

  • 您好,可以看一下下面链接的文档:
    www.ti.com.cn/.../slua544.pdf
  • 您好,现在使用调试器连接上了Battery Management Studio,设置了电池电量为15000mAH,可以采集到电压,电流,但是电量100%一直没有变,想咨询下如何配置才会显示正常电量,如何启动学习呢?

  • 请问楼主怎么解决的,在线等