BQ4050常用在电池包上,可以做保护以及温度电量采集

BQ4050中有多种数据读取方式,最简单的就是直接读寄存器,寄存器地址从0x01到0x78,读取格式就是

1.普通I2C的读取

例如使用STM32HAL读取电压

HAL_I2C_Mem_Read(&hi2c2, 0x17, 0x09, I2C_MEMADD_SIZE_8BIT, (uint8_t *)&temp, 2, 10);

0x17就是BQ4050的地址,0x09就是电压寄存器地址,该寄存器是16位,所以读2个。

2.块数据

需要按照SMBUS的块读写格式进行读写

格式是:先写入0x44寄存器要读取的块地址,然后再读取0x44,但需要注意的是,发送和接收都包含数据的长度,发送还需要crc8校验。

3.例如

读取0x0002的固件版本

void send_format(uint8_t *send_chr,uint16_t reg_addr){
	send_chr[0] = BQ_WRITE_ADDR;//0x16
	send_chr[1] = 0x44;//块
	send_chr[2] = 0x02;//数据长度
	send_chr[3] = (uint8_t)(reg_addr&0xff);//低位
	send_chr[4] = (uint8_t)((reg_addr>>8)&0xff);//高位
	send_chr[5] = crc8_fast(send_chr,5);//crc8校验
}

首先生成需要发送的数据格式,调用send_format(reg_data,0x0002);

send_format(reg_data,0x0002);	
HAL_I2C_Mem_Write(&hi2c2,BQ_READ_ADDR,0x44,I2C_MEMADD_SIZE_8BIT,&reg_data[2],4,50);

HAL_I2C_Mem_Read(&hi2c2,BQ_READ_ADDR,0x44,I2C_MEMADD_SIZE_8BIT,reg_data,40,50);

然后发送到0x44寄存器(只需要发送数据长度及后面的内容,前面的地址只是用来计算crc的),

然后读取,但这里会有一个问题,读的时候第一个数据也会是数据长度,但HAL的I2C并不能在读取的同时设置长度,如果先读一个,再读剩下的,BQ4050会重新发一遍长度(虽然也可以,但麻烦),我这里直接读一个较长的值,超过数据长度后会一直返回同一个值。最后根据数据长度截取一下就可以了,例如把读取的数据拼接成字符串。

	for(int temp_i2=1;temp_i2<reg_data[0]+1;temp_i2++){
		sprintf(temp_ch2,"0x%x ",reg_data[temp_i2]);
		strcat(send_chr,temp_ch2);
	}

4.最后附上crc8查表法以及数据表

const unsigned char crc8_table[256]={
0x0,0x7,0xe,0x9,0x1c,0x1b,0x12,0x15,0x38,0x3f,0x36,0x31,0x24,0x23,0x2a,0x2d,0x70,0x77,0x7e,0x79,0x6c,
0x6b,0x62,0x65,0x48,0x4f,0x46,0x41,0x54,0x53,0x5a,0x5d,0xe0,0xe7,0xee,0xe9,0xfc,0xfb,0xf2,0xf5,0xd8,
0xdf,0xd6,0xd1,0xc4,0xc3,0xca,0xcd,0x90,0x97,0x9e,0x99,0x8c,0x8b,0x82,0x85,0xa8,0xaf,0xa6,0xa1,0xb4,
0xb3,0xba,0xbd,0xc7,0xc0,0xc9,0xce,0xdb,0xdc,0xd5,0xd2,0xff,0xf8,0xf1,0xf6,0xe3,0xe4,0xed,0xea,0xb7,
0xb0,0xb9,0xbe,0xab,0xac,0xa5,0xa2,0x8f,0x88,0x81,0x86,0x93,0x94,0x9d,0x9a,0x27,0x20,0x29,0x2e,0x3b,
0x3c,0x35,0x32,0x1f,0x18,0x11,0x16,0x3,0x4,0xd,0xa,0x57,0x50,0x59,0x5e,0x4b,0x4c,0x45,0x42,0x6f,
0x68,0x61,0x66,0x73,0x74,0x7d,0x7a,0x89,0x8e,0x87,0x80,0x95,0x92,0x9b,0x9c,0xb1,0xb6,0xbf,0xb8,0xad,
0xaa,0xa3,0xa4,0xf9,0xfe,0xf7,0xf0,0xe5,0xe2,0xeb,0xec,0xc1,0xc6,0xcf,0xc8,0xdd,0xda,0xd3,0xd4,0x69,
0x6e,0x67,0x60,0x75,0x72,0x7b,0x7c,0x51,0x56,0x5f,0x58,0x4d,0x4a,0x43,0x44,0x19,0x1e,0x17,0x10,0x5,
0x2,0xb,0xc,0x21,0x26,0x2f,0x28,0x3d,0x3a,0x33,0x34,0x4e,0x49,0x40,0x47,0x52,0x55,0x5c,0x5b,0x76,
0x71,0x78,0x7f,0x6a,0x6d,0x64,0x63,0x3e,0x39,0x30,0x37,0x22,0x25,0x2c,0x2b,0x6,0x1,0x8,0xf,0x1a,
0x1d,0x14,0x13,0xae,0xa9,0xa0,0xa7,0xb2,0xb5,0xbc,0xbb,0x96,0x91,0x98,0x9f,0x8a,0x8d,0x84,0x83,0xde,
0xd9,0xd0,0xd7,0xc2,0xc5,0xcc,0xcb,0xe6,0xe1,0xe8,0xef,0xfa,0xfd,0xf4,0xf3
};
// 查表法计算CRC8
uint8_t crc8_fast(uint8_t *data, uint16_t len) {
    uint8_t crc = 0x00;  // 初始值
    for (uint16_t i = 0; i < len; i++) {
        crc = (uint8_t )crc8_table[(uint8_t)(crc ^ data[i])];
    }
    return crc;
}

块数据在芯片处在不同状态时,可读取的内容是不同的,还有data flash我暂时还没读取

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐