bms部分
---------------------------知识点BQ为什么串联电池----------------------------------
将多个电池并联可以组成一个能够提供低电压大电流的电池包,在低电压大电流的电池包应用场景时,连接电池包的电缆电阻即使很小,也会因为电缆上流过的大电流而在电缆上产生很大的线缆电压,这不是一个比较合适的设计。
而将多个电池串联组成一个能够提供大电压和小电流的电池包,在这样的电池包应用中,在电池包工作时,不再有很大的电流流过电缆,因而由于电缆电阻造成的线缆电压将不再是一个问题。但由于电池串联方式会引进的一个新问题,既串联方式会需要非常多个BMS通道对单体电池进行监测
一 、电池监控初始化 -- 250ms
1. 电池数据监控
主要监控单体/总体电芯的电压、温度、电流(单总一样)。
关于电压部分:需要提前计算 增益 和 校准参数。
在 BQ769X0 等电池管理芯片(BMS)的电压测量中,增益(Gain) 和偏移(Offset) 是实现高精度测量的核心校准参数,二者缺一不可。
1. 为什么需要增益(Gain)?
芯片内部 ADC 采集到的是数字量(LSB,最低有效位),例如 “1000” 这个数值本身没有物理单位,需要通过增益转换为实际电压。
实际电压(V)= [(ADC数字量 × 增益) + 偏移补偿] / 1000.0
2.为什么需要偏移(Offset)?
消除零漂误差:即使输入电压为 0,ADC 也可能输出非零的 LSB 值。
补偿环境影响:温度、湿度变化会导致 ADC 基准电压漂移,进而产生测量偏差。
void BQ769X0_GetADCGainOffset(void)
{// 读取ADC增益寄存器1的值(带CRC校验)BQ769X0_ReadRegisterByteWithCRC(ADCGAIN1, &(Registers.ADCGain1.ADCGain1Byte));// 读取ADC增益寄存器2的值(带CRC校验)BQ769X0_ReadRegisterByteWithCRC(ADCGAIN2, &(Registers.ADCGain2.ADCGain2Byte));/* 增益单位是uV/LSB(微伏/最低有效位),偏移单位是mV(毫伏)*/// 计算浮点型增益值:基础增益 + 增益寄存器1的相关位 + 增益寄存器2的相关位,再转换为伏/LSB//例如:总和 = 基础增益 + 第一步结果 + 第二步结果:1250 + 16 + 5 = 1271Gain = (ADCGAIN_BASE + ((Registers.ADCGain1.ADCGain1Byte & 0x0C) << 1) + ((Registers.ADCGain2.ADCGain2Byte & 0xE0)>> 5)) / 1000.0;// 计算整型增益值(用于后续整数运算,避免浮点误差)iGain = ADCGAIN_BASE + ((Registers.ADCGain1.ADCGain1Byte & 0x0C) << 1) + ((Registers.ADCGain2.ADCGain2Byte & 0xE0)>> 5);// 读取ADC偏移寄存器的值(带CRC校验),其中ADCOffset用了有符号数的补码形式,最高位是符号位(0正,1负),其他是数字位(+-:128字节)BQ769X0_ReadRegisterByteWithCRC(ADCOFFSET, &(Registers.ADCOffset));// 处理偏移值的符号(判断是否为负数): 11111011 & 10000000 = 10000000 (结果为0x80,非0)if (Registers.ADCOffset & 0x80) // 第7位为1表示负数(补码形式){Adcoffset = (int8_t)Registers.ADCOffset; // 直接将8位补码转换为有符号数}else // 第7位为0表示正数(补码形式){// 直接使用寄存器正数值作为偏移量Adcoffset = Registers.ADCOffset;}
}
// 更新电池单体电压数据
void BQ769X0_UpdateCellVolt(void)
{uint8_t index = 0; // 循环索引变量,用于遍历每个电池单体uint16_t iTemp = 0; // 临时存储16位原始ADC数据uint8_t *pRawADCData = NULL; // 指向原始ADC数据的指针uint32_t lTemp = 0; // 临时存储转换后的电压数据// 读取电池电压数据块// 从VC1_HI_BYTE寄存器开始读取,数据存储到Registers结构体中// 读取长度为:电池最大数量 × 2(每个电池电压占2字节)// 若读取失败,输出错误信息if (BQ769X0_ReadBlockWithCRC(VC1_HI_BYTE, &(Registers.VCell1.VCell1Byte.VC1_HI), BQ769X0_CELL_MAX << 1) != true){BQ769X0_ERROR("Update Cell Voltage Fail"); // 输出电压更新失败的错误信息}// 将指针指向 所有电池单体原始电压数据起始位置。pRawADCData指向高8位,pRawADCData + 1指向低8位;pRawADCData + 2指向下一个电池高8位pRawADCData = &Registers.VCell1.VCell1Byte.VC1_HI;