介紹一下手機電池電量檢測算法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},
};