mtk电池温度检测

平台:mt6735+mt6328 Android版本:Android5.1

手机里面电池通常有4个引脚,即电池的+、-极,ID引脚、NTC引脚。id引脚用来识别电池的类型,例如是锂电池还是镍氢电池,不过现在手机上基本用的都是锂电池了。而NTC引脚主要用来测量电池温度的,还可以用来检测手机有没有按上电池,那么这里就来说明这两个功能。

1. 电池检测
在mt6735+mt6328平台方案中,电池的NTC引脚需要接到mt6328的BATON引脚上,preloader中的检测代码如下:
int hw_check_battery(void)
{
    #ifdef MTK_DISABLE_POWER_ON_OFF_VOLTAGE_LIMITATION
        print("ignore bat check !\n");
        return 1;
    #else
        #if CFG_EVB_PLATFORM
            print("ignore bat check\n");
            return 1;
        #else
            U32 val=0;
			U32 ret_val;

			ret_val=pmic_config_interface( (U32)(MT6328_VTREF_CON0),
									 (U32)(1),
									 (U32)(MT6328_PMIC_RG_TREF_EN_MASK),
									 (U32)(MT6328_PMIC_RG_TREF_EN_SHIFT)
									 );

			ret_val=pmic_config_interface( (U32)(MT6328_VTREF_CON0),
									 (U32)(1),
									 (U32)(MT6328_PMIC_RG_TREF_ON_CTRL_MASK),
									 (U32)(MT6328_PMIC_RG_TREF_ON_CTRL_SHIFT)
									 );



            mt6325_upmu_set_baton_tdet_en(1);
            mt6325_upmu_set_rg_baton_en(1);
            val = mt6325_upmu_get_rgs_baton_undet();

            if(val==0)
            {
                print("bat is exist\n");
                return 1;
            }
            else
            {
                print("bat NOT exist\n");
                return 0;
            }
        #endif
    #endif
}

也就是通过hw_check_battery()函数来检测的,如果电池存在返回1,否则返回0。注意这个检测是通过PMIC来完成的。

之前遇到过电路有设计NTC检测电路,但是机器接稳压电源不能开机问题,需要禁掉该功能,怎么办?把MTK_DISABLE_POWER_ON_OFF_VOLTAGE_LIMITATION这个打开就可以了,在preloader/custom/project/project.mk里面把MTK_DISABLE_POWER_ON_OFF_VOLTAGE_LIMITATION这个宏赋值为yes就可以开机了。

但是改呢不只改这一处,还需要在ProjectConfig.mk里和kernel的config文件一起修改,否则编译时会有警告信息,但对于系统启动是无大碍的。

2. 电池温度检测
电池的温度也是通过NTC引脚来测量的,但是如果在kernel中把CONFIG_MTK_DISABLE_POWER_ON_OFF_VOLTAGE_LIMITATION宏打开了之后,温度测量功能也禁掉了。

温度测量是通过battery_meter.c中的force_get_tbat()函数完成的。在cust_battery_meter.h中,如果定义了CONFIG_MTK_DISABLE_POWER_ON_OFF_VOLTAGE_LIMITATION宏,那么FIXED_TBAT_25宏也被定义了,force_get_tbat()直接返回一个固定值温度25度。

再来说电池温度测量。

温度测量等效电路如下:

其中10k是一个温敏电阻,随着温度的升高,阻值降低,一般电池厂商会提供一个温度与阻值的曲线图,通过测量baton的电压值计算出阻值,然后根据阻值计算出温度值,这就是温度测量的原理。

在mt6735+mt6328平台上,上拉参考电压为1.8v,通过计算可以得到在25下,baton电压值大概为0.669v。

再来看force_get_tbat()函数。

int force_get_tbat(kal_bool update)
{
#if defined(CONFIG_POWER_EXT) || defined(FIXED_TBAT_25)
	bm_print(BM_LOG_CRTI, "[force_get_tbat] fixed TBAT=25 t\n");
	return 25;
#else
	int bat_temperature_volt = 0;
	int bat_temperature_val = 0;
	static int pre_bat_temperature_val = -1;
	int fg_r_value = 0;
	kal_int32 fg_current_temp = 0;
	kal_bool fg_current_state = KAL_FALSE;
	int bat_temperature_volt_temp = 0;
	int ret = 0;

	if (update == KAL_TRUE || pre_bat_temperature_val == -1) {
		/* Get V_BAT_Temperature */
		bat_temperature_volt = 2;
		ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP, &bat_temperature_volt);

		if (bat_temperature_volt != 0) {
#if defined(SOC_BY_HW_FG)
			fg_r_value = get_r_fg_value();

			ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &fg_current_temp);
			ret =
			    battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &fg_current_state);
			fg_current_temp = fg_current_temp / 10;

			if (fg_current_state == KAL_TRUE) {
				bat_temperature_volt_temp = bat_temperature_volt;
				bat_temperature_volt =
				    bat_temperature_volt - ((fg_current_temp * fg_r_value) / 1000);
			} else {
				bat_temperature_volt_temp = bat_temperature_volt;
				bat_temperature_volt =
				    bat_temperature_volt + ((fg_current_temp * fg_r_value) / 1000);
			}
#endif

			bat_temperature_val = BattVoltToTemp(bat_temperature_volt);
		}

	bm_print(BM_LOG_CRTI, "[force_get_tbat] %d,%d,%d,%d,%d,%d\n",
		 bat_temperature_volt_temp, bat_temperature_volt, fg_current_state, fg_current_temp,
		 fg_r_value, bat_temperature_val);
		pre_bat_temperature_val = bat_temperature_val;
	} else {
		bat_temperature_val = pre_bat_temperature_val;
	}
	return bat_temperature_val;
#endif
}
通过这里:
ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP, &bat_temperature_volt);

得到adc取得的baton电压值,中间又做了一些转换,然后调用BattVoltToTemp()函数。
int BattVoltToTemp(int dwVolt)
{
	kal_int64 TRes_temp;
	kal_int64 TRes;
	int sBaTTMP = -100;

	/* TRes_temp = ((kal_int64)RBAT_PULL_UP_R*(kal_int64)dwVolt) / (RBAT_PULL_UP_VOLT-dwVolt); */
	/* TRes = (TRes_temp * (kal_int64)RBAT_PULL_DOWN_R)/((kal_int64)RBAT_PULL_DOWN_R - TRes_temp); */

	TRes_temp = (RBAT_PULL_UP_R * (kal_int64) dwVolt);
	do_div(TRes_temp, (RBAT_PULL_UP_VOLT - dwVolt));

#ifdef RBAT_PULL_DOWN_R
	TRes = (TRes_temp * RBAT_PULL_DOWN_R);
	do_div(TRes, abs(RBAT_PULL_DOWN_R - TRes_temp));
#else
	TRes = TRes_temp;
#endif

	/* convert register to temperature */
	sBaTTMP = BattThermistorConverTemp((int)TRes);

	return sBaTTMP;
}
最后调用BattThermistorConverTemp()函数。
int BattThermistorConverTemp(int Res)
{
	int i = 0;
	int RES1 = 0, RES2 = 0;
	int TBatt_Value = -200, TMP1 = 0, TMP2 = 0;

	if (Res >= Batt_Temperature_Table[0].TemperatureR) {
		TBatt_Value = -20;
	} else if (Res <= Batt_Temperature_Table[16].TemperatureR) {
		TBatt_Value = 60;
	} else {
		RES1 = Batt_Temperature_Table[0].TemperatureR;
		TMP1 = Batt_Temperature_Table[0].BatteryTemp;

		for (i = 0; i <= 16; i++) {
			if (Res >= Batt_Temperature_Table[i].TemperatureR) {
				RES2 = Batt_Temperature_Table[i].TemperatureR;
				TMP2 = Batt_Temperature_Table[i].BatteryTemp;
				break;
			} else {
				RES1 = Batt_Temperature_Table[i].TemperatureR;
				TMP1 = Batt_Temperature_Table[i].BatteryTemp;
			}
		}

		TBatt_Value = (((Res - RES2) * TMP1) + ((RES1 - Res) * TMP2)) / (RES1 - RES2);
	}

	return TBatt_Value;
}
在BattThermistorConverTemp()函数里,跟据cust_battery_meter_table.h中定义的Batt_Temperature_Table表格来计算出温度值,这个表格是需要客户自己定制的,一般根据电池厂商提供的温度与阻值的曲线图来做修改。

完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值