mt6735电池电量计算

来源:互联网 发布:excel宏的编程实例 编辑:程序博客网 时间:2024/05/16 01:57

这里采用的是库伦积分计算电量的方式,硬件连接如下




通过cs_p,cs_n接到一个10豪欧的电阻来测量电流,进行电流积分来计算消耗的电量(DOD指放电深度)。

公式 DOD1 = DOD0 + (-Car/Qmax).
DOD1对应当前的放电深度.
DOD0对应初始的放电深度,通过开路电压得出起始电量值或者为rtc保存的值.
Car 为t时间内, 流过Rfg电阻电流的电量.

其中Car的值直接读寄存器便可得知.



kernel-3.18/drivers/power/mediatek/battery_meter.c

signed int battery_meter_initial(void){#if defined(CONFIG_POWER_EXT)return 0;#elsestatic kal_bool meter_initilized = KAL_FALSE;mutex_lock(&FGADC_mutex);if (meter_initilized == KAL_FALSE) {#ifdef MTK_MULTI_BAT_PROFILE_SUPPORTfgauge_get_profile_id();#endif#if defined(SOC_BY_AUXADC)g_auxadc_solution = 1;table_init();bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_AUXADC done\n");#endif#if defined(SOC_BY_HW_FG)fgauge_initialization();fgauge_algo_run_init();bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_HW_FG done\n");#endif#if defined(SOC_BY_SW_FG)g_auxadc_solution = 1;table_init();oam_init();bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_SW_FG done\n");#endifmeter_initilized = KAL_TRUE;}mutex_unlock(&FGADC_mutex);return 0;#endif}
这里用的是SOC_BY_HW_FG这种方式。

void fgauge_algo_run_init(void){int i = 0;int ret = 0;#ifdef INIT_SOC_BY_SW_SOCkal_bool charging_enable = KAL_FALSE;#if defined(CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) && !defined(SWCHR_POWER_PATH)if (LOW_POWER_OFF_CHARGING_BOOT != get_boot_mode())#endif/*stop charging for vbat measurement */battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);msleep(50);#endif/* 1. Get Raw Data */gFG_voltage = battery_meter_get_battery_voltage(KAL_TRUE);gFG_voltage_init = gFG_voltage;ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &gFG_Is_Charging);gFG_voltage = gFG_voltage + fgauge_compensate_battery_voltage_recursion(gFG_voltage, 5);/* mV */gFG_voltage = gFG_voltage + batt_meter_cust_data.ocv_board_compesate;bm_print(BM_LOG_CRTI, "[FGADC] SWOCV : %d,%d,%d,%d,%d,%d\n", gFG_voltage_init, gFG_voltage, gFG_current, gFG_Is_Charging, gFG_resistance_bat, gFG_compensate_value);#ifdef INIT_SOC_BY_SW_SOCcharging_enable = KAL_TRUE;battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);#endifret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);/* 1.1 Average FG_voltage */for (i = 0; i < batt_meter_cust_data.fg_vbat_average_size; i++)FGvbatVoltageBuffer[i] = gFG_voltage;FGbatteryVoltageSum = gFG_voltage * batt_meter_cust_data.fg_vbat_average_size;gFG_voltage_AVG = gFG_voltage;#ifdef Q_MAX_BY_CURRENT/* 1.2 Average FG_current */for (i = 0; i < FG_CURRENT_AVERAGE_SIZE; i++)FGCurrentBuffer[i] = gFG_current;FGCurrentSum = gFG_current * FG_CURRENT_AVERAGE_SIZE;gFG_current_AVG = gFG_current;#endif/* 2. Calculate battery capacity by VBAT */gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);gFG_capacity_by_v_init = gFG_capacity_by_v;/* 3. Calculate battery capacity by Coulomb Counter */gFG_capacity_by_c = fgauge_read_capacity(1);/* 4. update DOD0 */dod_init();gFG_current_auto_detect_R_fg_count = 0;for (i = 0; i < 10; i++) {ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);gFG_current_auto_detect_R_fg_total += gFG_current;gFG_current_auto_detect_R_fg_count++;}/* double check */if (gFG_current_auto_detect_R_fg_total <= 0) {bm_print(BM_LOG_CRTI, "gFG_current_auto_detect_R_fg_total=0, need double check\n");gFG_current_auto_detect_R_fg_count = 0;for (i = 0; i < 10; i++) {ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);gFG_current_auto_detect_R_fg_total += gFG_current;gFG_current_auto_detect_R_fg_count++;}}gFG_current_auto_detect_R_fg_result =    gFG_current_auto_detect_R_fg_total / gFG_current_auto_detect_R_fg_count;#if !defined(DISABLE_RFG_EXIST_CHECK)if (gFG_current_auto_detect_R_fg_result <= batt_meter_cust_data.current_detect_r_fg) {g_auxadc_solution = 1;bm_print(BM_LOG_CRTI, "[FGADC] Detect NO Rfg, use AUXADC report. (%d=%d/%d)(%d)\r\n", gFG_current_auto_detect_R_fg_result, gFG_current_auto_detect_R_fg_total, gFG_current_auto_detect_R_fg_count, g_auxadc_solution);} else {if (g_auxadc_solution == 0) {g_auxadc_solution = 0;bm_print(BM_LOG_CRTI, "[FGADC] Detect Rfg, use FG report. (%d=%d/%d)(%d)\r\n", gFG_current_auto_detect_R_fg_result, gFG_current_auto_detect_R_fg_total, gFG_current_auto_detect_R_fg_count, g_auxadc_solution);} else {bm_print(BM_LOG_CRTI, "[FGADC] Detect Rfg, but use AUXADC report. due to g_auxadc_solution=%d \r\n", g_auxadc_solution);}}#endif/* 5. Logging */bm_print(BM_LOG_CRTI, "[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v, gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY, gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage, batt_meter_cust_data.ocv_board_compesate, batt_meter_cust_data.r_fg_board_slope, gFG_voltage_init, batt_meter_cust_data.minerroroffset, gFG_DOD0, gFG_DOD1, batt_meter_cust_data.car_tune_value, batt_meter_cust_data.aging_tuning_value);update_fg_dbg_tool_value();}void fgauge_initialization(void){#if defined(CONFIG_POWER_EXT)#elseint i = 0;unsigned int ret = 0;/* gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(25); *//* gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(25); *//* 1. HW initialization */ret = battery_meter_ctrl(BATTERY_METER_CMD_HW_FG_INIT, NULL);/* 2. SW algorithm initialization */ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);i = 0;while (gFG_current == 0) {ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);if (i > 10) {bm_print(BM_LOG_CRTI, "[fgauge_initialization] gFG_current == 0\n");break;}i++;}ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);fgauge_construct_battery_profile_init();gFG_temp = force_get_tbat(KAL_FALSE);gFG_capacity = fgauge_read_capacity(0);gFG_capacity_by_c_init = gFG_capacity;gFG_capacity_by_c = gFG_capacity;gFG_capacity_by_v = gFG_capacity;gFG_DOD0 = 100 - gFG_capacity;bm_print(BM_LOG_CRTI, "[fgauge_initialization] gFG_DOD0 =%d %d\n", gFG_DOD0, gFG_capacity);gFG_BATT_CAPACITY = fgauge_get_Q_max(gFG_temp);gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(gFG_temp);gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(gFG_temp);ret = battery_meter_ctrl(BATTERY_METER_CMD_DUMP_REGISTER, NULL);bm_print(BM_LOG_CRTI, "[fgauge_initialization] Done HW_OCV:%d FG_Current:%d FG_CAR:%d tmp=%d capacity=%d Qmax=%d\n", gFG_voltage, gFG_current, gFG_columb, gFG_temp, gFG_capacity, gFG_BATT_CAPACITY);#if defined(FG_BAT_INT)pmic_register_interrupt_callback(FG_BAT_INT_L_NO, fg_bat_int_handler);pmic_register_interrupt_callback(FG_BAT_INT_H_NO, fg_bat_int_handler);#endif#endif}

根据下面这个打印就能看出电池的关键信息,这里特意注释下。

bm_print(BM_LOG_CRTI,"[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",

         gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v,
         gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY,
         gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage,
         batt_meter_cust_data.ocv_board_compesate, batt_meter_cust_data.r_fg_board_slope,
         gFG_voltage_init, batt_meter_cust_data.minerroroffset, gFG_DOD0, gFG_DOD1,
         batt_meter_cust_data.car_tune_value, batt_meter_cust_data.aging_tuning_value);

//是否充电  电流  库伦积分算出的剩余电量gFG_capacity_by_c  开路电压  根据开路电压算出的剩余电量

//根据积分算出的消耗的电量        开路电压算出的初始放电深度(百分比)  电池容量(mAh)  

//当前温度下的电池容量(mAh)   gFG_compensate_value    gFG_ori_voltage

//开路电压修正值                   r_fg_board_slope

//测量出的闭路电压               minerroroffset         初始的放电深度   当前放电深度(100-gFG_capacity_by_c)

//库仑计补偿值(需实验修正)        aging_tuning_value


dod_init();根据开路电压算出电量,如果rtc保存的电池电量与该电量不超过40%的误差,直接采用rtc保存的电量,提高用户体验。

否则采用开机的闭路电压(开机时的闭路电压作为开路电压)或者计算的开路电压作为起始的电量。

void dod_init(void){int ret = 0;signed int gFG_capacity_by_sw_ocv = gFG_capacity_by_v;/* use get_hw_ocv----------------------------------------------------------------- */ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);bm_print(BM_LOG_CRTI, "[FGADC] get_hw_ocv=%d, HW_SOC=%d, SW_SOC = %d\n", gFG_voltage, gFG_capacity_by_v, gFG_capacity_by_v_init);/* compare with hw_ocv & sw_ocv, check if less than or equal to 5% tolerance */if ((abs(gFG_capacity_by_v_init - gFG_capacity_by_v) > 5)    && (bat_is_charger_exist() == KAL_TRUE)) {gFG_capacity_by_v = gFG_capacity_by_v_init;}g_rtc_fg_soc = get_rtc_spare_fg_value();if (is_battery_remove_pmic() == 0 && (g_rtc_fg_soc != 0)&& batt_meter_cust_data.vbat_remove_detection) {bm_print(BM_LOG_CRTI, "[FGADC]is_battery_remove()==0 , use rtc_fg_soc%d\n", g_rtc_fg_soc);gFG_capacity_by_v = g_rtc_fg_soc;} else {if (((g_rtc_fg_soc != 0)&& (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <=batt_meter_cust_data.cust_poweron_delta_capacity_tolrance)      || (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) <  abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))     || ((g_rtc_fg_soc != 0)&& (get_boot_reason() == BR_WDT_BY_PASS_PWK || get_boot_reason() == BR_WDT    || get_boot_reason() == BR_TOOL_BY_PASS_PWK    || get_boot_reason() == BR_2SEC_REBOOT || get_boot_mode() == RECOVERY_BOOT))){gFG_capacity_by_v = g_rtc_fg_soc;} else {if (abs(gFG_capacity_by_v - gFG_capacity_by_sw_ocv) >    batt_meter_cust_data.cust_poweron_delta_hw_sw_ocv_capacity_tolrance) {bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d, gFG_capacity_by_sw_ocv=%d use SWOCV\n", gFG_capacity_by_v, gFG_capacity_by_sw_ocv);gFG_capacity_by_v = gFG_capacity_by_sw_ocv;} else {bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d, gFG_capacity_by_sw_ocv=%d use HWOCV\n", gFG_capacity_by_v, gFG_capacity_by_sw_ocv);}}}bm_print(BM_LOG_CRTI, "[FGADC] g_rtc_fg_soc=%d, gFG_capacity_by_v=%d\n", g_rtc_fg_soc, gFG_capacity_by_v);if (gFG_capacity_by_v == 0 && bat_is_charger_exist() == KAL_TRUE) {gFG_capacity_by_v = 1;bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d\n", gFG_capacity_by_v);}gFG_capacity = gFG_capacity_by_v;gFG_capacity_by_c_init = gFG_capacity;gFG_capacity_by_c = gFG_capacity;gFG_DOD0 = 100 - gFG_capacity;gFG_DOD1 = gFG_DOD0;gfg_percent_check_point = gFG_capacity;if (batt_meter_cust_data.change_tracking_point) {gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);} else {/* gFG_15_vlot = fgauge_read_v_by_capacity(86); //14% */gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);if ((gFG_15_vlot > 3800) || (gFG_15_vlot < 3600)) {bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot(%d) over range, reset to 3700\n", gFG_15_vlot);gFG_15_vlot = 3700;}}}

获取电池电量的函数

signed int battery_meter_get_battery_percentage(void){fgauge_algo_run();return gFG_capacity_by_c;}

void fgauge_algo_run(void){int i = 0;int ret = 0;#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORTint columb_delta = 0;int charge_current = 0;#endif/* Reconstruct table if temp changed; */fgauge_construct_table_by_temp();/* 1. Get Raw Data */ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &gFG_Is_Charging);gFG_voltage = battery_meter_get_battery_voltage(KAL_FALSE);gFG_voltage_init = gFG_voltage;gFG_voltage = gFG_voltage + fgauge_compensate_battery_voltage_recursion(gFG_voltage, 5);/* mV */gFG_voltage = gFG_voltage + batt_meter_cust_data.ocv_board_compesate;ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);/* add by willcai 2014-12-18 begin */if (BMT_status.charger_exist == KAL_FALSE) {if (gFG_Is_offset_init == KAL_FALSE) {for (i = 0; i < batt_meter_cust_data.fg_vbat_average_size; i++)FGvbatVoltageBuffer[i] = gFG_voltage;FGbatteryVoltageSum =    gFG_voltage * batt_meter_cust_data.fg_vbat_average_size;gFG_voltage_AVG = gFG_voltage;gFG_Is_offset_init = KAL_TRUE;}/* 1.1 Average FG_voltage */    /**************** Averaging : START ****************/if (gFG_voltage >= gFG_voltage_AVG)gFG_vbat_offset = (gFG_voltage - gFG_voltage_AVG);elsegFG_vbat_offset = (gFG_voltage_AVG - gFG_voltage);if (gFG_vbat_offset <= batt_meter_cust_data.minerroroffset) {FGbatteryVoltageSum -= FGvbatVoltageBuffer[FGbatteryIndex];FGbatteryVoltageSum += gFG_voltage;FGvbatVoltageBuffer[FGbatteryIndex] = gFG_voltage;gFG_voltage_AVG =    FGbatteryVoltageSum / batt_meter_cust_data.fg_vbat_average_size;gFG_voltage = gFG_voltage_AVG;FGbatteryIndex++;if (FGbatteryIndex >= batt_meter_cust_data.fg_vbat_average_size)FGbatteryIndex = 0;bm_print(BM_LOG_FULL, "[FG_BUFFER] ");for (i = 0; i < batt_meter_cust_data.fg_vbat_average_size; i++)bm_print(BM_LOG_FULL, "%d,", FGvbatVoltageBuffer[i]);bm_print(BM_LOG_FULL, "\r\n");} else {bm_print(BM_LOG_FULL, "[FG] Over MinErrorOffset:V=%d,Avg_V=%d, ", gFG_voltage, gFG_voltage_AVG);gFG_voltage = gFG_voltage_AVG;bm_print(BM_LOG_FULL, "Avg_V need write back to V : V=%d,Avg_V=%d.\r\n", gFG_voltage, gFG_voltage_AVG);}} elsegFG_Is_offset_init = KAL_FALSE;/* 2. Calculate battery capacity by VBAT */gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);/* 3. Calculate battery capacity by Coulomb Counter */gFG_capacity_by_c = fgauge_read_capacity(1);/* 4. voltage mode */if (volt_mode_update_timer >= volt_mode_update_time_out) {volt_mode_update_timer = 0;fg_voltage_mode();} else {volt_mode_update_timer++;}/* 5. Logging */pr_err( "[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v, gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY, gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage, batt_meter_cust_data.ocv_board_compesate, batt_meter_cust_data.r_fg_board_slope, gFG_voltage_init, batt_meter_cust_data.minerroroffset, gFG_DOD0, gFG_DOD1, batt_meter_cust_data.car_tune_value, batt_meter_cust_data.aging_tuning_value);update_fg_dbg_tool_value();}

gFG_capacity_by_c = fgauge_read_capacity(1);

signed int fgauge_read_capacity(signed int type){signed int voltage;signed int temperature;signed int dvalue = 0;signed int temp_val = 0;if (type == 0) {/* for initialization *//* Use voltage to calculate capacity */voltage = battery_meter_get_battery_voltage(KAL_TRUE);/* in unit of mV */temperature = force_get_tbat(KAL_FALSE);dvalue = fgauge_get_dod0(voltage, temperature, KAL_FALSE);/* need compensate vbat */} else {/* Use DOD0 and columb counter to calculate capacity */dvalue = fgauge_update_dod();/* DOD1 = DOD0 + (-CAR)/Qmax */}gFG_DOD1 = dvalue;temp_val = dvalue;dvalue = 100 - temp_val;if (dvalue <= 1) {dvalue = 1;bm_print(BM_LOG_FULL, "[fgauge_read_capacity] dvalue<=1 and set dvalue=1 !!\r\n");}return dvalue;}

signed int fgauge_update_dod(void){signed int FG_dod_1 = 0;int adjust_coulomb_counter = batt_meter_cust_data.car_tune_value;if (gFG_DOD0 > 100) {gFG_DOD0 = 100;bm_print(BM_LOG_FULL, "[fgauge_update_dod] gFG_DOD0 set to 100, gFG_columb=%d\r\n", gFG_columb);} else if (gFG_DOD0 < 0) {gFG_DOD0 = 0;bm_print(BM_LOG_FULL, "[fgauge_update_dod] gFG_DOD0 set to 0, gFG_columb=%d\r\n", gFG_columb);} else {}gFG_temp = force_get_tbat(KAL_FALSE);if (temperature_change == 1) {gFG_BATT_CAPACITY = fgauge_get_Q_max(gFG_temp);bm_print(BM_LOG_CRTI, "[fgauge_update_dod] gFG_BATT_CAPACITY=%d, gFG_BATT_CAPACITY_aging=%d, gFG_BATT_CAPACITY_init_high_current=%d\r\n", gFG_BATT_CAPACITY, gFG_BATT_CAPACITY_aging, gFG_BATT_CAPACITY_init_high_current);temperature_change = 0;}FG_dod_1 = gFG_DOD0 - ((gFG_columb * 100) / gFG_BATT_CAPACITY_aging);bm_print(BM_LOG_FULL, "[fgauge_update_dod] FG_dod_1=%d, adjust_coulomb_counter=%d, gFG_columb=%d, gFG_DOD0=%d, gFG_temp=%d, gFG_BATT_CAPACITY=%d  %d\r\n", FG_dod_1, adjust_coulomb_counter, gFG_columb, gFG_DOD0, gFG_temp, gFG_BATT_CAPACITY, gFG_BATT_CAPACITY_aging);if (FG_dod_1 > 100) {FG_dod_1 = 100;bm_print(BM_LOG_FULL, "[fgauge_update_dod] FG_dod_1 set to 100, gFG_columb=%d\r\n", gFG_columb);} else if (FG_dod_1 < 0) {FG_dod_1 = 0;bm_print(BM_LOG_FULL, "[fgauge_update_dod] FG_dod_1 set to 0, gFG_columb=%d\r\n", gFG_columb);} else {}return FG_dod_1;}
这里看下客制化参数

&bat_meter {/* cust_battery_meter.h *//* ADC resistor  */r_bat_sense = <4 >;r_i_sense = <4 >;r_charger_1 = <330 >;r_charger_2 = <39 >;temperature_t0 = <110 >;temperature_t1 = <0 >;temperature_t2 = <25 >;temperature_t3 = <50 >;temperature_t = <255 >;/* this should be fixed, never change the value */fg_meter_resistance = <0 >;/* Qmax for 0mA */q_max_pos_50 = <1463 >;q_max_pos_25 = <1437 >;q_max_pos_0 = <1220 >;q_max_neg_10 = <1137 >;/* Qmax for 400mA, said high current */q_max_pos_50_h_current = <1511 >;q_max_pos_25_h_current = <1462 >;q_max_pos_0_h_current = <818 >;q_max_neg_10_h_current = <149 >;/* Discharge percentage, 1: D5, 0: D2 */oam_d5 = <1 >;change_tracking_point = <1 >;/* SW OCV tracking setting */cust_tracking_point = <1 >;cust_r_sense = <68 >;cust_hw_cc = <0 >;aging_tuning_value = <103 >;cust_r_fg_offset = <0 >;ocv_board_compesate = <0 >;r_fg_board_base = <1000 >;r_fg_board_slope = <1000 >;car_tune_value = <104 >;/* HW Fuel gague  */current_detect_r_fg = <10 >;/* Unit: mA */minerroroffset = <1000 >;fg_vbat_average_size = <18 >;r_fg_value = <10 >;/* Unit: mOhm */cust_poweron_delta_capacity_tolrance = <40 >;cust_poweron_low_capacity_tolrance = <5 >;cust_poweron_max_vbat_tolrance = <90 >;cust_poweron_delta_vbat_tolrance = <30 >;cust_poweron_delta_hw_sw_ocv_capacity_tolrance = <10 >;/* Fixed battery temperature */fixed_tbat_25 = <0 >;/* Battery remove detecton */vbat_remove_detection = <0>;     battery_profile_t0     battery_profile_t1     battery_profile_t2     battery_profile_t3
其中r_charger_1 r_charger_2是vcdt脚的分压电阻的阻值
要通过实验修正car_tune_value的值,影响积分值的准确性

填写电池厂商提供的110°(-10) 0° 25° 50°下的电池容量与开路电压的关系表,注意数组长度一致以及电池容量值q_max_pos和最大电流值q_max_pos_xx_h_current

r_fg_value库仑计的电阻值(豪欧)

car_tune_value修正的基本方法,给定一个标准电流(如电流1000mA),如果读出cpu读出的电流值(工程模式下的电流值假设是1078mA),那么修正值为1000/1078=0.93,也就是

测量出的电流要乘以系数0.93才是准确的电量值,这里car_tune_value为93。

操作方法,一路电源接电池接口的正极,另一端接任意系统地,这一路电源没有电流经过电阻r_fg。

另一路电源的正极接系统地,负极接电池的负极,限制一个电流的输出。具体的操作方法可参考mtk的文档Fuel Gauge Application Notes_V1.2.pptx

static signed int fgauge_read_current(void *data){...dvalue = ((dvalue * batt_meter_cust_data.car_tune_value) / 100);...}


参考文档

Fuel_Gauge_introduce.pdf

Fuel Gauge Application Notes_V1.2.pptx 

http://blog.csdn.net/fdaopeng/article/details/8803996