第06章 读取电池相关数值
约 1190 字大约 4 分钟
2026-07-21
6.1 读取电压值
CELL VOLTAGE 寄存器
每个电芯的电压存储在两个连续寄存器中(VCx_HI和VCx_LO)。

读取流程:
- 根据电池编号获取电池寄存器位置
- 读取对应电池寄存器的值
- 把寄存器的高低位合并为采样值
- 把采样值根据公式、增益值和偏移量计算出物理值
void App_Bat_GetCellVoltage(void)
{
uint8_t vc_reg_vals[BAT_NUM * 2];
if (Int_BQ769_ReadRegs(BQ_VC1_HI, BAT_NUM * 2, vc_reg_vals) != 0) {
DEBUG_PRINTLN("ERROR: 读取电池电压寄存器失败");
return;
}
for (uint8_t i = 0; i < BAT_NUM; i++) {
uint16_t v_adc = ((vc_reg_vals[i * 2] & 0x3F) << 8) | vc_reg_vals[i * 2 + 1];
g_bat_voltages[i] = (v_adc * g_bq_gain + g_bq_offset) / 1000.0; // 单位: V
}
}6.2 读取电池包电压值
BAT_HI、BAT_LO 寄存器
存储的电压为总电压值的1/4,计算公式:
V_total = (4 × gain × ADC + N × offset) / 1000 (V)

其中N为电池节数。
void App_Bat_GetTotalVolage(void)
{
uint8_t total_reg_vals[2];
if (Int_BQ769_ReadRegs(BQ_BAT_HI, 2, total_reg_vals) != 0) {
DEBUG_PRINTLN("ERROR: 读取电池总电压寄存器失败");
return;
}
uint16_t total_adc = (total_reg_vals[0] << 8) | total_reg_vals[1];
g_total_voltage = (4 * g_bq_gain * total_adc + (BAT_NUM * g_bq_offset)) / 1000.0;
}6.3 读取电池电流值
CC_HI、CC_LO 寄存器(库仑计数器)
通过库仑计数器测量检流电阻两端电压,然后通过欧姆定律计算电流:
I = V_cc / R_sense


本项目使用的检流电阻为5mΩ。
void App_Bat_GetCurrent(void)
{
uint8_t cc_reg_vals[2];
if (Int_BQ769_ReadRegs(BQ_CC_HI, 2, cc_reg_vals) != 0) {
DEBUG_PRINTLN("ERROR: 读取库伦计数器寄存器失败");
return;
}
int16_t cc_adc = (cc_reg_vals[0] << 8) | cc_reg_vals[1];
if (cc_adc < 0) cc_adc = -cc_adc; // 取绝对值
float cc_voltage = (cc_adc * 8.44) / 1000.0; // 电压(mV)
g_bat_current = cc_voltage / 5.0; // 电流(A)
}6.4 读取电池温度
TS1_HI、TS1_LO 寄存器
使用外部1kΩ的103AT热敏电阻来测量温度。



测量方法:
- 配置
SYS_CTRL1寄存器选择外部热敏电阻(TEMP_SEL=1) - 读取TS1电压寄存器值
- 根据电压计算电阻值:
R = (V × 10000) / (3.3 - V) - 通过查表将电阻值转换为温度
热敏电阻温度转换表(10K NTC 5%),单位:Ω
// -55℃ ~ +125℃ 共181个值,以下为部分示例
324, 333, 342, 351, 361, 371, // 120 ~ 125℃
382, 393, 404, 415, 427, 439, 451, 464, 478, 491, // 110 ~ 119℃
// ... (完整查表数据请参考源码)
8397, 8765, 9151, 9557, 10000, 10431, 10901, ..., // 20 ~ 29℃
// ...
302890, 323623, 346049, 370283, 396426, ..., // -49 ~ -40℃
593686, 631466, 669165, 705664, 739500 // -55 ~ -50℃void App_Bat_GetTemperature(void)
{
uint8_t temp_reg_vals[2];
if (Int_BQ769_ReadRegs(BQ_TS1_HI, 2, temp_reg_vals) != 0) {
DEBUG_PRINTLN("ERROR: 读取温度寄存器失败");
return;
}
uint16_t temp_adc = ((temp_reg_vals[0] & 0x3F) << 8) | temp_reg_vals[1];
float temp_voltage = (temp_adc * 382) / 1000000.0; // 电压(V)
float temp_resistance = (temp_voltage * 10000.0) / (3.3 - temp_voltage); // 电阻(Ω)
g_bat_temperature = Com_BQ769_GetTemperatureByRes(temp_resistance); // 查表
}6.5 读取电池电量(SOC)
锂电池电压-电量特性
锂电池通常使用放电电压来判断剩余电量。以3.7V的18650三元锂电池为例:满电时约4.2V,完全放电后约3.3V。

电压-剩余电量对照表(25℃):(单位:mV)
3282, // 0%~1%
3309, 3334, 3357, 3378, 3398, 3417, 3434, 3449, 3464, 3477, // 1%~10%
3489, 3500, 3510, 3520, 3528, 3536, 3543, 3549, 3555, 3561, // 11%~20%
// ... (完整查表数据请参考源码)
4067, 4080, 4092, 4105, 4118, 4131, 4145, 4158, 4172, 4185, // 91~100%温度补偿
由于温度变化会影响电池的电压-容量关系,需要进行温度补偿:
- 常温段(0~40℃):
SOC = SOC × (1 + (-0.005) × (T - 25)) - 低温段(<0℃):需分段计算,低温段补偿系数增加0.002/℃
- 高温段(>40℃):需分段计算,高温段补偿系数减小0.003/℃


计算流程
void App_Bat_GetSOC(void)
{
// 1. 根据每个电芯电压查表计算SOC,求平均值
float total_soc = 0.0f;
for (uint8_t i = 0; i < BAT_NUM; i++) {
total_soc += Com_BQ769_GetSocByVol(g_bat_voltages[i] * 1000);
}
g_bat_soc = total_soc / BAT_NUM;
// 2. 温度补偿
if (g_bat_temperature >= 0 && g_bat_temperature <= 40) {
g_bat_soc = g_bat_soc * (1 + (-0.005) * (g_bat_temperature - 25));
} else if (g_bat_temperature < 0) {
g_bat_soc = g_bat_soc * (1 + (-0.005) * (0 - 25)) +
g_bat_soc * (1 + (-0.005 + 0.002) * (g_bat_temperature - 0));
} else if (g_bat_temperature > 40) {
g_bat_soc = g_bat_soc * (1 + (-0.005) * (40 - 25)) +
g_bat_soc * (1 + (-0.005 - 0.003) * (g_bat_temperature - 40));
}
}6.6 屏幕显示
void App_Display_Update(void)
{
// 显示总电压
sprintf((char *)display_buffer, "U:%4.1fV", g_total_voltage);
Int_OLED_ShowString(0, 16, display_buffer, 16, 1);
// 显示电流
sprintf((char *)display_buffer, "I:%4.1fA", g_bat_current);
Int_OLED_ShowString(64, 16, display_buffer, 16, 1);
// 显示温度
sprintf((char *)display_buffer, "T:%4.1fC", g_bat_temperature);
Int_OLED_ShowString(0, 32, display_buffer, 16, 1);
// 显示电池剩余电量
sprintf((char *)display_buffer, "S:%4.1f%%", g_bat_soc);
Int_OLED_ShowString(64, 32, display_buffer, 16, 1);
taskENTER_CRITICAL();
Int_OLED_Refresh();
taskEXIT_CRITICAL();
}文档生成于: 2026-07-21
