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

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.逻辑分析仪抓取波形

Star Xu:

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

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

,

user6414905:

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

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_InitTypeDefGPIO_InitStructure={0};//SDAGPIO_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;elseGPIO_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高电平期间,数据线低elseBQ_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();elseBQ_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);//读数据,发送ACKdata[1] = BQ_I2C_ReadByte(0);//读数据,发送NACKBQ_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();//等待ACKBQ_I2C_WriteByte(data[1]);//发送数据BQ_I2C_RecvWait_ACK();//等待ACKBQ_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;
}

,

Star Xu:

您好,您可以用EV2300只读取一个数,如电池电压,然后用示波器把i2c的波形抓取下来。再抓一下自己软件编写的的i2c波形,同样读取这个电压,看看两者有什么区别,很快就能定位到问题。比如ACK信号有没有?发送地址对不对?发送命令时序对不对等。

,

user6414905:

您好,目前驱动OK了,可以读取的电压,但是如何配置Bq27520,读取电量呢?您是否可以提供一下指导,比如参看那份数据手册等?

,

Star Xu:

您好,可以看一下下面链接的文档:
www.ti.com.cn/…/slua544.pdf

,

user6414905:

您好,现在使用调试器连接上了Battery Management Studio,设置了电池电量为15000mAH,可以采集到电压,电流,但是电量100%一直没有变,想咨询下如何配置才会显示正常电量,如何启动学习呢?

,

xin zhou1:

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

赞(0)
未经允许不得转载:TI中文支持网 » BQ27520电量计IIC读取失败
分享到: 更多 (0)