介绍一下手机电池电量检测算法SOC_BY_AUXADC的程序设计,SOC_BY_AUXADC即通过读取电池电压来估测电池电量值。
获取电池剩余电量值的函数入口:
kal_int32 auxadc_algo_run(void)
{
kal_int32 val=0;
gFG_voltage = battery_meter_get_battery_voltage();
val = fgauge_read_capacity_by_v(gFG_voltage);
bm_print(BM_LOG_CRTI, "[auxadc_algo_run] %d,%d\n", gFG_voltage, val);
return val;
}
函数battery_meter_get_battery_voltage()负责获取电池当前电压,函数fgauge_read_capacity_by_v(gFG_voltage)通过插
值算法来估测电池剩余电量。
battery_meter_get_battery_voltage()函数定义:
kal_int32 battery_meter_get_battery_voltage(void)
{
int ret=0;
int val=5;
val = 5; //set avg times
ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &val);
g_sw_vbat_temp = val;
return val;
}
电池电压采集5次,然后返回电压平均值。
fgauge_read_capacity_by_v(gFG_voltage)函数定义:
kal_int32 fgauge_read_capacity_by_v(kal_int32 voltage)
{
int i = 0, saddles = 0;
BATTERY_PROFILE_STRUC_P profile_p;
kal_int32 ret_percent = 0;
profile_p = fgauge_get_profile(TEMPERATURE_T);
if (profile_p == NULL)
{
bm_print(BM_LOG_CRTI, "[FGADC] fgauge get ZCV profile : fail !\r\n");
return 100;
}
saddles = fgauge_get_saddles();
if (voltage > (profile_p+0)->voltage)
{
return 100; // battery capacity, not dod
}
if (voltage < (profile_p+saddles-1)->voltage)
{
return 0; // battery capacity, not dod
}
for (i = 0; i < saddles - 1; i++)
{
if ((voltage <= (profile_p+i)->voltage) && (voltage >= (profile_p+i+1)->voltage))
{
ret_percent = (profile_p+i)->percentage +
(
(
( ((profile_p+i)->voltage) - voltage ) *
( ((profile_p+i+1)->percentage) - ((profile_p + i)->percentage) )
) /
( ((profile_p+i)->voltage) - ((profile_p+i+1)->voltage) )
);
break;
}
}
ret_percent = 100 - ret_percent;
return ret_percent;
}
考虑到不同温度下电池电压和电量的对应关系会发生改变的情况,程序中函数fgauge_get_profile(TEMPERATURE_T)就是根据当前
的温度值TEMPERATURE_T查找到对应的电压电量值对应表。最后根据voltage搜索表中对应的电压区间,通过斜率换
算得到用掉的电量,通过ret_percent = 100 - ret_percent获取剩余电量。
BATTERY_PROFILE_STRUC_P fgauge_get_profile(kal_uint32 temperature)
{
switch (temperature)
{
case TEMPERATURE_T0:
return &battery_profile_t0[0];
break;
case TEMPERATURE_T1:
return &battery_profile_t1[0];
break;
case TEMPERATURE_T2:
return &battery_profile_t2[0];
break;
case TEMPERATURE_T3:
return &battery_profile_t3[0];
break;
case TEMPERATURE_T:
return &battery_profile_temperature[0];
break;
default:
return NULL;
break;
}
}
// T2 25C
BATTERY_PROFILE_STRUC battery_profile_t2[] =
{
{0 , 4176},
{1 , 4157},
{3 , 4143},
{4 , 4128},
{6 , 4114},
......
{90 , 3692},
{92 , 3690},
{93 , 3685},
{95 , 3679},
{96 , 3646},
{98 , 3585},
{99 , 3499},
{100 , 3356},
{100 , 3307},
};