RK3566,rk817上TS脚模拟输入功能用作NTC检测

1. 硬件原理分析

在我的板子上客户提出了检测电池温度的需求,为了满足需求同时减少成本,我们的硬件工程师将电池的NTC直接连接到了rk817这快PMIC的TS脚上,并且没有串联任何的电阻,在我们的一贯思维里一般都是串联一个电阻,然后在电阻跟NTC之间拉条线作为检测口,但是这个项目却并非如此,于是我们查阅rk817的手册我们可以了解到TS脚作为GPIO/模拟功能的描述如下:

TS_FUN
TS_FUN: TS pin function selection
0:source current to TS pin
1:external voltage input directly

根据手册我们可以知道TS脚作为模拟口的时候可选择是从外部输入电压还是从内部输出电流来检测,而我们则选择的是从内部输出电流到TS脚位,然后在NTC上产生电压,再通过TS脚采集AD值计算相应的电阻值

2.软件实现

2.1修改rk817相关的寄存器配置
2.1.1 gas_gauge_ADC_CONFIG0寄存器

该寄存器上的TS_ADC_EN位要配置为1,源码里面已经完成了配置:

rk817_bat_field_write(battery, TS_ADC_EN, ENABLE);
2.1.2 gas_gauge_ADC_CONFIG1寄存器

该寄存器上的VOL_ADC_TSCUR_SEL确保这一位描述了从TS脚输出的电流大小,规格书描述如下:

VOL_ADC_TSCUR_SEL
VOL_ADC_TSCUR_SEL: TS pin flow out 
	current in active state
	00:10uA 01:20uA 10:30uA 11:40uA

在这里我们选择的是默认的也就是10uA

2.1.3 CODEC_AREF_RTCFG1寄存器

通过该寄存器上的REF_ADC_SEL位我们可以知道ADC的参考电压是多少,描述如下:

REF_ADC_SEL
Select the ADC reference voltage 
	0: 1.2V 1: 1.5V

我们选择的是默认值,也就是1.2v

2.2 添加自己的温度检测函数

首先我们找到rk817采集电池温度的位置,如下:

static int rk817_battery_get_property(struct power_supply *psy,
				      enum power_supply_property psp,
				      union power_supply_propval *val)
{
	struct rk817_battery_device *battery = power_supply_get_drvdata(psy);

	switch (psp) {

	....	//---------------------------------------此处为了篇幅我省略了部分代码

	case POWER_SUPPLY_PROP_TEMP:
		if(bat_ntc_count >= 100)
		{
			val->intval = battery_read_temp()/100;
		}
		if (battery->pdata->bat_mode == MODE_VIRTUAL)
			val->intval = VIRTUAL_TEMPERATURE;
		break;

	....	//---------------------------------------此处为了篇幅我省略了部分代码
	default:
		return -EINVAL;
	}

	return 0;
}

在这里是通过 val->intval = battery_read_temp()/100;,来获取温度的我们将这里注释掉,添加成我们集编写的函数,我们自己编写的函数如下:

struct temp_data {
	int tempR;
	int tempC;
};
static const struct temp_data bat_temp_table[] = {
	{1956520, -40}, {1849171, -39}, {1748452, -38}, {1653910, -37}, {1565125, -36},
	{1481710, -35}, {1403304, -34}, {1329576, -33}, {1260215, -32}, {1194936, -31},
	{1133471, -30}, {1075649, -29}, {1021155, -28}, {969776, -27},  {921315, -26},
	{875588, -25},  {832424, -24},  {791663, -23},  {753157, -22},  {716768, -21},
	{682367, -20},  {649907, -19},  {619190, -18},  {590113, -17},  {562579, -16},
	{536496, -15},  {511779, -14},  {488349, -13},  {466132, -12},  {445058, -11},
	{425062, -10},  {405997, -9},   {387905, -8},   {370729, -7},   {354417, -6},
	{338922, -5},   {324197, -4},   {310200, -3},   {296890, -2},   {284231, -1},
	{272186, 0},    {260760, 1},    {249877, 2},    {239509, 3},    {229629, 4},
	{220211, 5},    {211230, 6},    {202666, 7},    {194495, 8},    {186698, 9},
	{179255, 10},   {172139, 11},   {165344, 12},   {158856, 13},   {152658, 14},
	{146735, 15},   {141075, 16},   {135664, 17},   {130489, 18},   {125540, 19},
	{120805, 20},   {116281, 21},   {111947, 22},   {107795, 23},   {103815, 24},
	{100000, 25},   {96342, 26},    {92835, 27},    {89470, 28},    {86242, 29},
	{83145, 30},    {80181, 31},    {77337, 32},    {74609, 33},    {71991, 34},
	{69479, 35},    {67067, 36},    {64751, 37},    {62526, 38},    {60390, 39},
	{58336, 40},	{56357, 41},	{54454, 42},	{52623, 43},	{50863, 44},
	{49169, 45},	{47539, 46},	{45971, 47},	{44461, 48},	{43008, 49},
	{41609, 50},	{40262, 51},	{38964, 52},	{37714, 53},	{36510, 54},
	{35350, 55},	{34231, 56},	{33152, 57},	{32113, 58},	{31110, 59},
	{30143, 60},	{29224, 61},	{28337, 62},	{27482, 63},	{26657, 64},
	{25861, 65},	{25093, 66},	{24351, 67},	{23635, 68},	{22943, 69},
	{22275, 70},	{21627, 71},	{21001, 72},	{20396, 73},	{19811, 74},
	{19245, 75},	{18698, 76},	{18170, 77},	{17658, 78},	{17164, 79},
	{16685, 80},	{16224, 81},	{15777, 82},	{15345, 83},	{14927, 84},
	{14521, 85},	{14129, 86},	{13749, 87},	{13381, 88},	{13025, 89},
	{12680, 90},	{12343, 91},	{12016, 92},	{11700, 93},	{11393, 94},
	{11096, 95},	{10807, 96},	{10528, 97},	{10256, 98},	{9993, 99},
	{9738, 100},	{9492, 101},	{9254, 102},	{9022, 103},	{8798, 104},
	
};
#define BAT_TEMP_TEBLE_NUM (sizeof(bat_temp_table) / sizeof(bat_temp_table[0]))
int  vt_get_battery_temp(struct rk817_battery_device *battery)
{
	int val = 0, res = 0, i= 0,ret = 0;
    
	val = rk817_bat_field_read(battery, BAT_TS_H) << 8;
	val |= rk817_bat_field_read(battery, BAT_TS_L);
	//cur = rk817_bat_field_read(battery,VOL_ADC_TSCUR_SEL);	//TS out current select     参考电压选择

	//val = (1200*val)/65536;	//
	//res = val*100;///(10/1000);
    //res  = res *10; //扩大10倍

	val = val*18;	//
    res  = val; //扩大10倍
	//printk("Vantron print Ntc RValue is: %d   -----------------------------------------\r\n",res); 
	for(i = 0; i < BAT_TEMP_TEBLE_NUM-1;i++)
	{
		if ((res > bat_temp_table[i + 1].tempR) && (res <= bat_temp_table[i].tempR))
		{
			ret = bat_temp_table[i].tempC;
			break;
		}
	}
	//printk("Vantron print Ntc CValue is: %d   -----------------------------------------\r\n",ret);
	//  return (ret*10);
	return ret;
}

我们将温度所对应的电阻值做成一个表方便查找,在rk817_battery_get_property的调用如下:

static int rk817_battery_get_property(struct power_supply *psy,
				      enum power_supply_property psp,
				      union power_supply_propval *val)
{
	struct rk817_battery_device *battery = power_supply_get_drvdata(psy);
	static int bat_ntc_count = 0;
	bat_ntc_count++;

	switch (psp) {

	....	//---------------------------------------此处为了篇幅我省略了部分代码
	case POWER_SUPPLY_PROP_TEMP:
		if(bat_ntc_count >= 100)
		{
			//val->intval = battery_read_temp()/100;
			val->intval = vt_get_battery_temp(battery);///100;	// 20220322--k.li
		}
			

		if (battery->pdata->bat_mode == MODE_VIRTUAL)
			val->intval = VIRTUAL_TEMPERATURE;
		break;
	....	//------------------------------------------此处为了篇幅我省略了部分代码
	default:
		return -EINVAL;
	}

	return 0;
}

编译烧录到我们的板子中,然后就可以通过cat 命令查看我们的电池温度了,命令如下:

rk66_gnrc:/sys/class/power_supply/battery $ ls
capacity        charge_counter  charge_full_design  device  online  status     temp              type    voltage_now
capacity_level  charge_full     current_now         health  power   subsystem  time_to_full_now  uevent  wakeup6
rk66_gnrc:/sys/class/power_supply/battery $ cat temp
22
rk66_gnrc:/sys/class/power_supply/battery $ 

可以看到电池温度为22摄氏度。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32 NTC检测是指在STM32微控制器中使用NTC热敏电阻来测量温度的功能NTC热敏电阻是一种电阻器,其电阻随环境温度的变化而变化,因此可以用来检测环境温度。 在STM32中,我们可以通过ADC模块来读取NTC热敏电阻的电阻值,并使用计算公式将其转换为温度值。这个计算公式是基于NTC热敏电阻的电阻温度特性曲线来实现的,因此需要知道NTC热敏电阻的特性参数。 一般来说,我们需要在实际测量环境中校准NTC热敏电阻的参数,以确保测量结果的准确性。此外,还需要注意NTC热敏电阻的安装方式和环境温度对测量结果的影响,以避免误差的产生。 总之,STM32 NTC检测是一种方便、快速、准确地获取环境温度信息的方法,可以应用于各种需要温度测量的场合,例如智能家居、气象监测、温度控制等。 ### 回答2: stm32是一款微控制器,它可以通过配合NTC电阻来检测温度。NTC电阻是一种负温度系数电阻,当温度升高时,它的电阻值会逐渐降低。因此,通过测量NTC电阻的电阻值可以推算出当前的温度。 实现NTC检测的关键在于选择合适的NTC电阻和测量电路。NTC电阻的选择应考虑到其温度响应范围、线性度和稳定性等因素,而测量电路应设计合适的电压、电流和放大系数。 在STM32中,可以利用其内置的模拟转换器(ADC)和温度传感器进行NTC电阻的温度计算。首先需要通过ADC获取NTC电阻的电阻值,然后利用已知的参考温度和电阻值计算NTC电阻的温度值。最后,通过处理器发送温度数据给外部设备。 总之,STM32与NTC电阻的配合可以实现精确的温度监测和控制,可广泛应用于工业自动化、家电和环境监测等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值