MTK Fuel Gauge兼容多电池,软件&硬件上应该怎么做?
时间:10-02
整理:3721RD
点击:
如果一个手机上面,要兼容多个手机电池,应该怎么做?
如果需要兼容多个电池:
硬件上首先要有一个独立的电池IDpin,供软件做区分。
一般做法,是电池端,制作多一个pin,该pin连接的阻值不同,通过BB端的ADC,获取的电压值就不同。
从而软件上可以做区分。
下面以兼容三个电池为例:
1.制作3个Battery的profile,也即需要制作三个battery的zcv表格。
2.在gauge init的时候, 可以通过读battery的id pin的电压值,
//不同电压范围,对应不同电池
kal_int32 g_battery_id_voltage[] = {500000, 1000000, -1};//0~0.5V for battery 0, 0.5~1V for battery 1, -1 for the last one (battery 2)
extern int IMM_GetOneChannelValue_Cali(int Channel, int*voltage);
kal_uint32 g_fg_battery_id = 0;
//通过类似这个函数,去获取battery的ID号,并赋值给g_fg_battery_id,供后面battery table的加载
void fgauge_get_profile_id(void)
{
int id_volt = 0;
int id = 0;
int ret = 0;
//获取电池ID pin的电池电压
ret = IMM_GetOneChannelValue_Cali(BATTERY_ID_CHANNEL_NUM, &id_volt);
if(ret != 0)
bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]id_volt read fail\n");
else
bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]id_volt = %d\n", id_volt);
//判断电池总个数是否正确
if ( (sizeof(g_battery_id_voltage)/sizeof(kal_int32)) != TOTAL_BATTERY_NUMBER)
{
bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]error! voltage range incorrect!\n");
return;
}
//判断是哪个电池,将ID填入g_fg_battery_id这个变量
for (id = 0; id < TOTAL_BATTERY_NUMBER; id++)
{
if(id_volt < g_battery_id_voltage[id])
{
g_fg_battery_id = id;
break;
}
else if (g_battery_id_voltage[id] == -1)
{
g_fg_battery_id = TOTAL_BATTERY_NUMBER-1;
}
}
bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]Battery id (%d)\n", g_fg_battery_id);
}
3.请将不同电池的信息,填写到cust_battery_meter_table.h
a.
默认NTC表格
BATT_TEMPERATURE Batt_Temperature_Table[]
修改成
BATT_TEMPERATURE Batt_Temperature_Table[3][17]
b.
将默认dod0&ocv表格
// T0 -10C
BATTERY_PROFILE_STRUC battery_profile_t0[]
// T1 0C
BATTERY_PROFILE_STRUC battery_profile_t1[]
// T2 25C
BATTERY_PROFILE_STRUC battery_profile_t2[]
// T3 50C
BATTERY_PROFILE_STRUC battery_profile_t3[]
修改成
// T0 -10C
BATTERY_PROFILE_STRUC battery_profile_t0[3][86]
// T1 0C
BATTERY_PROFILE_STRUC battery_profile_t1[3][86]
// T2 25C
BATTERY_PROFILE_STRUC battery_profile_t2[3][86]
// T3 50C
BATTERY_PROFILE_STRUC battery_profile_t3[3][86]
将默认r&ocv表格
// T0 -10C
R_PROFILE_STRUC r_profile_t0[]
// T1 0C
R_PROFILE_STRUC r_profile_t1[]
// T2 25C
R_PROFILE_STRUC r_profile_t2[]
// T3 50C
R_PROFILE_STRUC r_profile_t3[]
修改成
// T0 -10C
R_PROFILE_STRUC r_profile_t0[3][86]
// T1 0C
R_PROFILE_STRUC r_profile_t1[3][86]
// T2 25C
R_PROFILE_STRUC r_profile_t2[3][86]
// T3 50C
R_PROFILE_STRUC r_profile_t3[3][86]
4.如何获取电池信息的表格
battery_meter.c对下面两个函数稍作修改:
fgauge_get_profile
fgauge_get_profile_r_table
如下:
获取电池profile table
//获取不同温度,不同电池,ocv&dod0表格
//电池ID已经放在[g_fg_battery_id]变量里
BATTERY_PROFILE_STRUC_P fgauge_get_profile(kal_uint32 temperature)
{
switch (temperature)
{
case TEMPERATURE_T0:
return &battery_profile_t0[g_fg_battery_id][0];
break;
case TEMPERATURE_T1:
return &battery_profile_t1[g_fg_battery_id][0];
break;
case TEMPERATURE_T2:
return &battery_profile_t2[g_fg_battery_id][0];
break;
case TEMPERATURE_T3:
return &battery_profile_t3[g_fg_battery_id][0];
break;
case TEMPERATURE_T:
return &battery_profile_temperature[0];
break;
default:
return NULL;
break;
}
}
//获取不同电池ocv&r的表格
R_PROFILE_STRUC_P fgauge_get_profile_r_table(kal_uint32 temperature)
{
switch (temperature)
{
case TEMPERATURE_T0:
return &r_profile_t0[g_fg_battery_id][0];
break;
case TEMPERATURE_T1:
return &r_profile_t1[g_fg_battery_id][0];
break;
case TEMPERATURE_T2:
return &r_profile_t2[g_fg_battery_id][0];
break;
case TEMPERATURE_T3:
return &r_profile_t3[g_fg_battery_id][0];
break;
case TEMPERATURE_T:
return &r_profile_temperature[0];
break;
default:
return NULL;
break;
}
}
5.如何根据电池ID(g_fg_battery_id)获取Qmax
//定义3个电池的Qmax&Qmax_current
/* Qmax for battery */
kal_int32 g_Q_MAX_POS_50[] = {3895, 3895, 3895};
kal_int32 g_Q_MAX_POS_25[] = {3895, 3895, 3895};
kal_int32 g_Q_MAX_POS_0[] = {3895, 3895, 3895};
kal_int32 g_Q_MAX_NEG_10[] = {3895, 3895, 3895};
kal_int32 g_Q_MAX_POS_50_H_CURRENT[] = {3865, 3865, 3865};
kal_int32 g_Q_MAX_POS_25_H_CURRENT[] = {3865, 3865, 3865};
kal_int32 g_Q_MAX_POS_0_H_CURRENT[] = {3865, 3865, 3865};
kal_int32 g_Q_MAX_NEG_10_H_CURRENT[] = {3865, 3865, 3865};
fgauge_get_Q_max
fgauge_get_Q_max_high_current
修改如下:
kal_int32 fgauge_get_Q_max(kal_int16 temperature)
{
kal_int32 ret_Q_max=0;
kal_int32 low_temperature = 0, high_temperature = 0;
kal_int32 low_Q_max = 0, high_Q_max = 0;
if (temperature <= TEMPERATURE_T1)
{
low_temperature = (-10);
low_Q_max = g_Q_MAX_NEG_10[g_fg_battery_id];
high_temperature = TEMPERATURE_T1;
high_Q_max = g_Q_MAX_POS_0[g_fg_battery_id];
if(temperature < low_temperature)
{
temperature = low_temperature;
}
}
else if (temperature <= TEMPERATURE_T2)
{
low_temperature = TEMPERATURE_T1;
low_Q_max = g_Q_MAX_POS_0[g_fg_battery_id];
high_temperature = TEMPERATURE_T2;
high_Q_max = g_Q_MAX_POS_25[g_fg_battery_id];
if(temperature < low_temperature)
{
temperature = low_temperature;
}
}
else
{
low_temperature = TEMPERATURE_T2;
low_Q_max = g_Q_MAX_POS_25[g_fg_battery_id];
high_temperature = TEMPERATURE_T3;
high_Q_max = g_Q_MAX_POS_50[g_fg_battery_id];
if(temperature > high_temperature)
{
temperature = high_temperature;
}
}
ret_Q_max = low_Q_max +
( (
(temperature - low_temperature) *
(high_Q_max - low_Q_max)
) /
(high_temperature - low_temperature)
);
bm_print(BM_LOG_FULL, "[fgauge_get_Q_max] Q_max = %d\r\n", ret_Q_max);
return ret_Q_max;
}