NTC 温度采样 二分查表及公式法

NTC 温度采样:

本文记录对NTC 温度采样,分别采用二分查表法及公式法进行描述

资源下载链接:Excel 生成数组表 https://download.csdn.net/download/qq_41359157/88326839?spm=1001.2014.3001.5503


NTC参数:

在这里插入图片描述

NTC采样电路:

在这里插入图片描述

一、 二分查表法:

二分法,二分查找很高效,假设数据大小是n,每次查找后数据都会缩小为原来的一半,也就是会除以2。二分法查找针对的是一个有序的数据集合(升序或降序排列)。
(1)首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
(2)如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤(1)的操作。
比如,我们需要查找4。

  1. 先取一半为6, 6 大于 4。则说明要找的数在前一半,此时end需要挪到mid-1处
  2. 再取一半为3, 3 小于 4。则说明要找的数在后一半,此时start需要挪到mid+1处
  3. 再次查找,则可以找到目标值。当然对于温度来讲,只知道一个范围区间,这个下面再讲
    在这里插入图片描述因为NTC的AD值正好是表中的值概率很小,很可能查不到,但是我们可以知道落在了哪个区间,所以要处理的数据基本上在两个温度的区间,如果要显示小数,两个温度区间可以看成是线性的,通过局部线性化就可以计算出温度的值。
    假设ADC采样的值是2075,则对应在数据表中的2093~2048之间,及在24 ℃ ~ 25 ℃之间
    计算方式按照线性处理如下:
    在这里插入图片描述
    代码部分:

头文件部分:这里我生成了两个表格,一个是ADC的表格,一个是与其对应的温度表格

static const uint16 NTC_adc_table[] = 
{
	3996, 3988, 3981, 3972, 3964, 3955, 3945, 3935, 3924, 3912, 	
	3900, 3887, 3874, 3860, 3845, 3830, 3813, 3796, 3778, 3760, 	
	3740, 3720, 3698, 3676, 3653, 3629, 3604, 3578, 3551, 3524, 	
	3495, 3465, 3435, 3403, 3371, 3337, 3303, 3267, 3231, 3194, 	
	3156, 3118, 3078, 3038, 2997, 2955, 2913, 2870, 2826, 2782, 	
	2738, 2693, 2648, 2602, 2556, 2510, 2464, 2417, 2371, 2324, 	
	2278, 2231, 2185, 2139, 2093, 2048, 2002, 1957, 1913, 1868, 	
	1825, 1781, 1739, 1697, 1655, 1614, 1574, 1534, 1495, 1456, 	
	1419, 1382, 1346, 1310, 1275, 1241, 1208, 1175, 1143, 1112, 	
	1081, 1052, 1023, 994, 967, 940, 914, 888, 863, 839, 	
	815, 792, 770, 748, 727, 707, 687, 668, 649, 631, 	
	613, 596, 579, 563, 547, 532, 517, 502, 488, 475, 	
	462, 449, 436, 424, 413, 401, 390, 380, 369, 359, 	
	350, 340, 331, 322, 314, 305, 297, 289, 282, 274, 	
	267, 260, 253, 247, 240, 234, 228, 222, 217, 211, 	
	206, 201, 196, 191, 186, 181, 177, 173, 168, 164, 	
	160
};

static const sint16 NTC_temperature_table[] = 
{
	-40, -39, -38, -37, -36, -35, -34, -33, -32, -31, 	
	-30, -29, -28, -27, -26, -25, -24, -23, -22, -21, 	
	-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, 	
	-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 	
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 	
	10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 	
	20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 	
	30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 	
	40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 	
	50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 	
	60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 	
	70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 	
	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 	
	90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 	
	100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 	
	110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 	
	120
};

源文件部分:

#define TSP_SHORT_CIRCUIT_THRESHOLD 	20U			/*!<NTC short-circuit */
#define TSP_OPEN_CIRCUIT_THRESHOLD 		4090U		/*!<NTC open-circuit */

/*------------------------------------------------------------------------------*/
/*!
 * \brief       tsp_BinaryTableSearch 
 * \details     Calculation of NTC temperature by binary table lookup method
 * \param[in]   adc_val  current adc value 
 * \param[out]  float32  Temperature( degree centigrade )         
*/
/*------------------------------------------------------------------------------*/
static float32 tsp_BinaryTableSearch( uint16 adc_val )
{
	uint16 start = 0U, end = 0U, mid = 0U;

	/* Get the arry length */
	end = ( sizeof( NTC_adc_table )/ sizeof( NTC_adc_table[0] ) ) - 1U;

	/* Data anomaly judgment */
	if( adc_val <= TSP_SHORT_CIRCUIT_THRESHOLD )
	{
		return 1.0F;
	}
	else if( adc_val >= TSP_OPEN_CIRCUIT_THRESHOLD )
	{
		return 2.0F;
	}
	else if( adc_val > NTC_adc_table[0] )
	{
		return 3.0F;
	}
	else if( adc_val < NTC_adc_table[end - 1U] )
	{
		return 4.0F;
	}
	else
	{
		/* MISRA-C coding rules */
	}

	while ( start <= end )
	{
		/* Get the mid value */
		mid = (start + end) >> 1; 

		/* Just find */
		if( adc_val ==  NTC_adc_table[mid] )
		{
			break;
		}
		/* Right in between two temperature points */
		if( ( adc_val < NTC_adc_table[mid] ) && ( adc_val > NTC_adc_table[mid+1U] ) )
		{
			break;
		}

		/* The current AD value less than the middle of the array indicates 
		 * the second half of the number to look for 
		 */
		if( adc_val < NTC_adc_table[mid] )
		{
			start = mid + 1U; 
		}
		/* The current AD value greater than the middle of the array indicates 
		 * that the number to be found is in the first half 
		 */
		else if( adc_val > NTC_adc_table[mid] )
		{
			end = mid - 1U;
		}
		else
		{
			/* MISRA-C coding rules */
		}
	}

 	return ( NTC_temperature_table[mid] + (float)( NTC_adc_table[mid] - adc_val ) / (float)( NTC_adc_table[mid]-NTC_adc_table[mid+1] ) );
	
	// return (mid-40) +  (float)(NTC_adc_table[mid] -key)/(float)(NTC_adc_table[mid]-NTC_adc_table[mid+1]);
}

这里我们可以采用两种方法,一种是通过ADC的值索引到当前表中的位置,再根据这个mid位置索引到温度表格中的值,然后进行计算。
还有一种就是注释的部分:

 return (mid-40) +  (float)(NTC_adc_table[mid] -key)/(float)(NTC_adc_table[mid]-NTC_adc_table[mid+1]);

这里的mid - 40代表的是,这个表格前面有40个负值温度,通过mid-40 可以得到当前温度的整数部分。这种方法比较固定,写程序时得确定当前温度范围值。

如果采用第二种方法,只需要配置参数,生成头文件即可。

excel表格配置:
在这里插入图片描述
只需要填写相关属性参数,点击Publish即可生成头文件

二、 公式法 —— 温度系数B值计算法:

在这里插入图片描述在这里插入图片描述
这里T1和T2指的是K度即开尔文温度

X
R1NTC在T(K)温度下的阻值, T1温度下的阻值
R2NTC在25℃下的阻值(10K、5K、100K…)即:在额定温度 TN ( K )时的 NTC 热敏电阻阻值,T2常温下的标称阻值。
BNTC 热敏电阻的材料常数,又叫热敏指数 (3435,3950…)
T1NTC的温度
T2273.15+25 (开尔文基数 + 额定阻值下的温度)

通过转换可以得到温度T1与电阻Rt的关系:
在这里插入图片描述

因为C语言的math.h中没有ln表达,有log可以进行替代,
这里可以将ln换算成log:
在这里插入图片描述
其他博客统一写上了:
对应的摄氏温度t=T1-273.15,同时+0.5的误差矫正。

本人通过跟查表法对比,发现加了0.5误差矫正反而就多了0.5,所以实际程序中不添加0.5进行误差矫正。

代码部分:

#ifdef NTC_SUPPORT

#include <math.h>

#define TSP_NTC_B_VALUE   			3950U 			/*!<NTC B value */
#define TSP_NTC_RATED_TEMP          25U   			/*!<NTC rated temperature(25℃) */
#define TSP_NTC_RATED_RES           10000.0F 		/*!<NTC rated resistance 10K*/
#define TSP_NTC_KELVIN_VALUE		273.15F			/*!<NTC kelvin value */
#define TSP_NTC_T2_VALUE			TSP_NTC_KELVIN_VALUE + TSP_NTC_RATED_TEMP
#define TSP_NTC_ERROR_VALUE			0.5F 			/*!<NTC error,log replace of ln, need to add the error */
#define TSP_ADC_FULL_SCALE 		    4095.0F	        /*!<ADC scale*/
#define TSP_ADC_VOLTAGE_REF 	    3.3F	        /*!<Voltage reference*/
/*
*	Temperature Configuration Data:
*		TSP_HOT_TEMP_LIMIT
*		TSP_COLD_TEMP_LIMIT
*		TSP_MAX_SAMPLE_NUM
*		TSP_NTC_B_VALUE
*       TSP_NTC_RATED_TEMP
*       TSP_NTC_RATED_RES
* 	Temperature Conversion Equations:
* 		T[Volt] = T[ADC] * (3.3 / 1023)
*		T[degree] = ( 1 / ( ln(Rt/Rp) / B + 1/T2 ) ) - 273.15
*/

double tsp_ln(double a)
{
	int N = 15;
	int k , nk;
	double x, xx , y;
	x = ( a - 1 ) / ( a + 1 );
	xx = x * x;
	nk = 2 * N + 1;
	y = 1.0 / nk;
	for( k = N; k > 0; k-- )
	{
		nk = nk - 2;
		y = ( 1.0 / nk ) + ( xx * y );
	}

	return ( 2.0 * x * y );
}

/*------------------------------------------------------------------------------*/
/*!
 * \brief       tsp_ResistanceToTemperature 
 * \details     Convert NTC resistance to temperature,
 * 				important: Array sorting from large to small search
 * \param[in]   adc_val  Current adc value    
 * \param[out]  float32  Temperature( degree centigrade )    
*/
/*------------------------------------------------------------------------------*/
static float32 tsp_ResistanceToTemperature( uint16 adc_val )
{
	float32 B_value  = TSP_NTC_B_VALUE;
	float32 Rp_value = TSP_NTC_RATED_RES;
	float32 T1 = 0.0F;
	float32 T2 = TSP_NTC_T2_VALUE;
	float32 Rt_value = 0.0F;
	float32 volt_val = 0.0F;

	/* Data anomaly judgment */
	if( adc_val <= TSP_SHORT_CIRCUIT_THRESHOLD )
	{
		return 1.0F;
	}
	else if( adc_val >= TSP_OPEN_CIRCUIT_THRESHOLD )
	{
		return 2.0F;
	}
	else
	{
		/* MISRA-C coding rules */
	}

	/* Convert to voltage */
	volt_val = ((float32) adc_val * TSP_ADC_VOLTAGE_REF) / TSP_ADC_FULL_SCALE;

	/* Get the NTC resistance value */
	Rt_value = volt_val / ( ( TSP_ADC_VOLTAGE_REF - volt_val ) / TSP_NTC_RATED_RES );
	
	/* Operational formula */
	T1 = ( 1.0F / ( ( log( Rt_value / Rp_value ) / B_value ) + ( 1.0F / T2 ) ) );

	/* Operational formula */
	// T1 = ( 1.0F / ( ( tsp_ln( Rt_value / Rp_value ) / B_value ) + ( 1.0F / T2 ) ) );

	/* Kelvin value convert to degree celsius value */
	T1 = T1 - TSP_NTC_KELVIN_VALUE;

	return ( T1 );
}
#endif

注意:如果用于单片机程序,使用 <math.h>,且不开优化( -O1, -O2, -O3…)的话,程序会额外占用5KB的flash空间。开了程序优化,则可以正常使用math库中的log函数,不会额外占用flash空间。
当然,如果不想开优化,但是又想使用ln函数,可以自己实现。

double tsp_ln(double a)

该函数就是一种实现ln的算法。实际测试对比基本符合log函数功能


总结:

查表法与B值公式法两者测量温度对比:
在这里插入图片描述
可以发现两者结果基本一致,只有小数点后第二位有0.01~0.02的误差,对于NTC采样来讲是可以接受的

我个人比较喜欢使用B值公式法,这样不用生成查表的表格,只需要将宏定义对应的关键参数进行配置,就可以满足不同规格的NTC电阻。



PS: 如何转换摄氏度为开尔文:
0摄氏度等于273.15开尔文 0℃ = 273.15K
例:将20℃转换为开尔文
T(K) = 20℃ + 273.15 = 293.15K

  • 16
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: NTC(Negative Temperature Coefficient)是一种负温度系数热敏电阻,在测量温度方面具有广泛应用。为了获取准确的温度信息,需要进行数据采集和插值查表的过程。 首先,需要进行数据采集。通过N个温度点,测量NTC电阻的实际电阻值。这些温度点可以遍布整个温度范围,以确保有足够的数据点进行后续的查表和插值计算。 接下来,将采集到的温度和相应的电阻值记录在表格中。这个表格被称为NTC温度-电阻特性曲线表或查表表格。这个表格包含了不同温度下的电阻值,可以作为后续插值计算的基础。 当需要测量某个温度时,可以通过查表的方式来获取对应温度下的电阻值。如果所需的温度点在已有的数据点之间,可以使用插值的方来计算出该温度下的电阻值。插值算通常使用线性插值、拉格朗日插值或牛顿插值等方,根据已有数据点的位置和数值,来推算出目标温度对应的电阻值。 通过采集温度和进行插值查表,可以更准确地获取NTC电阻在不同温度下的电阻值,从而计算出对应的温度值。这种方温度测量方面被广泛使用,具有简单、快速和准确的优点。 ### 回答2: NTC(Negative Temperature Coefficient)是一种负温度系数热敏电阻,其电阻值随温度变化而改变。为了准确测量温度,我们可以使用NTC来采集温度数据,并通过插值查表的方式来获取实际温度值。 NTC温度插值查表的方是基于已知温度-电阻值对的数据表。通常,这个数据表由厂家根据NTC的特性进行实验测定,并提供给用户使用。 当我们需要测量温度时,首先需要将NTC安装在要测量的物体表面或者近距离接触到物体中。NTC的电阻值将受到物体的温度影响而改变。然后,我们将读取NTC的电阻值,这个值将作为输入。 接下来,我们可以使用数据表来进行插值计算。我们首先找到两个最接近的已知温度-电阻值对,然后通过线性插值的方计算出我们所需的温度值。 线性插值的公式为: 温度 = (电阻值 - R₁) × (温度₂ - 温度₁) ÷ (R₂ - R₁) + 温度₁ 其中,R₁和R₂分别是离目标电阻值最近的两个已知电阻值,温度₁和温度₂分别是对应的已知温度。 通过这种方式,我们可以根据NTC的电阻值获取相应的温度值。这种方虽然有一定的误差,但在实际应用中通常可以提供足够的精度来满足需求。 总的来说,NTC采集温度插值查表是一种常用的方,通过将NTC的电阻值与已知温度值进行插值计算,可以得到准确的温度值。这种方简单有效,特别适用于温度测量和控制领域。 ### 回答3: NTC采集温度插值查表是一种常见的温度测量方NTC(Negative Temperature Coefficient)热敏电阻是一种电阻值随温度变化呈负相关关系的元件,常用于测量温度。而NTC的电阻-温度特性是非线性的,故无直接通过测量电阻值来准确获得温度信息。 为了解决这个问题,人们通常会在预先测量一系列已知温度下的NTC电阻值,并将其制作成一张查表。这张表能够通过对已知的NTC电阻值进行插值,来预测未知温度值。 使用NTC采集温度插值查表的步骤如下: 首先,将NTC热敏电阻与电路相连。当电阻与环境温度接触时,它的电阻值会发生变化。 然后,通过电阻测量装置测量NTC的电阻值。 接下来,使用这个测量到的NTC电阻值,在查表中找到离测量值最近的两个已知温度对应的电阻值。 然后,通过对这两个电阻值进行插值运算,根据已知温度与电阻值的关系,计算出未知温度的估计值。 最后,根据查表得到的估计温度值,以及相应的插值误差,来进行相应的校准和调整。 总之,NTC采集温度插值查表是一种通过测量NTC电阻值来预测温度的方。通过建立一个电阻值与温度值的对应关系查表,可以用已知的电阻值来推测未知的温度值,并提供温度测量的准确性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Terry.Z_1009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值