NTC是负温度系数的简写,全称是Negative temperature coefficient.意思是随着温度的升高,电阻值呈现下降趋势。常用作温度传感器。这里有一个式子表示负温度系数的电阻值:
RT=R0*exp(B (1/T-1/T0))
RT为周围温度为T (K) 时的电阻值,R0是周围温度为T0 (K) 时的电阻值,注意这里的温度是开尔文温度。B为B常数. 请记住这个B常数,它也是材料常数,一般在25摄氏度下测得。B值和电阻的温度系数正相关,也就是B值越大,电阻的温度系数越高。而温度系数是指每增加1℃,电阻值的变化率。也就是说,B值越大,电阻值的变化随着温度的增加越多,灵敏度越高.
标题
如下图所示,温度测量常用电阻串联分压,ADC采集的方式进行。根据热敏电阻的特性,理想情况下,设VCC=3.3V,在25℃时,Rt = 10KΩ,此时ADC采集到的电压值为3.3V/2 = 1.65V.
关于ADC的采集,我这里就不多讲了,我这里主要讲得到ADC转换值以后,如何得到温度值。
第一步是找到自己的热敏电阻的数据手册,查找B值和查看 它的温度-阻值曲线图,我使用的一款热敏电阻是SDNT1608,阻值10KΩ,精度±1%,B值为3450K(25°C~50°C).数据手册中的温度-阻值特性曲线如下图所示:
下面介绍两种温度转换的方法:计算法和查表法
首先看计算法 ,回到我们的公式 RT=R0*exp(B*(1/T-1/T0)),这里R=10K,开氏度 = 摄氏度+273.15,所以T0 = 273.15+25 ,这里的exp()指的是e^(),所以我们可以反求出当前温度:
T = 1 / [ln (RT/R0) / B + 1/T0]
那么我们唯一需要知道的就是Rt的值,回到上面的测电路,由电阻分压,设热敏电阻两端电压为VRt,固定10K电阻两端电压为VR,可以知道VR/VRt = R/Rt,从而:
Rt = R*(3.3-VR)/VR
而我们实际得到的VR是转换后的ADC值,即VR = 3.3*ADC_Value/4096,把上面的式子整理一下,代码如下,需要注意的是计算出来的温度是开尔文温度,因此需要减去K值。最后的0.5是修正值。有条件的情况下,与标准仪器相比,来得到这个值。
//温度转换 //参数:ADC转换值 float temp_trans(u16 ADC_value) { //数据进入前,可先做滤波处理 float Rt=0; //NTC电阻 float R=10000; //10K固定阻值电阻 float T0=273.15+25;//转换为开尔文温度 float B=3450; //B值 float Ka=273.15; //K值 float VR=0;//电压值 VR=(float) (ADC_value/4096*3.3); //转换成电压值 Rt=(3.3-VR)*10000/VR;//计算Rt temp=1/(1/T0+log(Rt/R)/B)-Ka+0.5; //计算温度 return temp; }一般而言,厂家会提供NTC电阻的温度与电阻表,如下图所示,基于这个表,我们只需要计算出当前热敏电阻的阻值Rt,然后查照此表,得到最接近的温度值即可。实际使用中,我们根据使用环境,摘出一部分表,比如我这里需要监控MOS的温度,所以我只需要25℃-100℃附近的值。。
例子:厂家给出的温度阻值表我们定义一个数组来存放这些值,为了方便,我们直接存放ADC转换的值,可以做一个表格,计算出温度对应的ADC的值。请注意我这里只做了整数倍的表格,如果需要用到小数点后面的温度,正确的方法是使用公式RT=R0*exp(B (1/T-1/T0))在excel中计算得到不进值为0.1℃的温度表。我这里就不举例了。
已知等式关系:
Rt = R*(3.3-VR)/VR (1)
VR = 3.3*ADC_Value/4096 (2)
整理两式:
ADC_Value = VR*4096/3.3 =3.3*R/(Rt+R)*4096/3.3 = R/(Rt+R)*4096
下面是计算得到的表格:
//阻值表 #define Max_len 81 static const u16 R10K_TAB[Max_len] = { 2048, 2010, 1972, 1934, 1897, 1859, 1822, 1786, 1750, 1714, //25-34℃ 1679, 1644, 1609, 1575, 1541, 150,8 1475, 1443, 1412, 1380, //35-44℃ 1350, 1319, 1290, 1260, 1232, 1204, 1176, 1149, 1122, 1096, //45-54℃ 1070, 1045, 1021, 997, 973, 950, 928, 906, 884, 863, //55-64℃ 843, 823, 803, 784, 765, 747, 729, 711, 694, 678, //65-74℃ 661, 646, 630, 615, 600, 586, 572, 558, 545, 532, //75-84℃ 519, 507, 494, 483, 472, 460, 449, 439, 428, 418, //85-94℃ 409, 399, 390, 381, 372, 363, 355, 347, 339, 331, //95-104℃ 324 //105℃ };接下来的步骤就是得到ADC的转换值,然后查表对比,输出温度值。思路是这样,但实际上应该是有问题的。留着后面来完善。
//逐次查找 //参数:ADC转换值 //12位ADC:0-4095 u8 Find_temp_order(u16 ADC_Value) { u8 index; for(i=0;i<Max_len;i++) { if((ADC_Value-50)<=R10K_TAB[i] || (ADC_Value+50)<=R10K_TAB[i]) //比较 return 25+index; //返回温度值 } return 0; //返回错误值 } //二分法查找 //参数:*array: 待查数组 // *target:ADC转换值 u8 Find_temp_dich(u16 *array,u16 target) { u16 first = 2048,last = 324,mid; u16 counter = 0; while(first >= last) //这里是降序排列 { counter++; mid = (first + last) / 2; //中间值 if(array[mid] > target) //目标值在后一半 { last = mid + 1; } else if(array[mid] < target) //目标值在前一半 { last = mid - 1; } else {return mid + 25;} //返回索引值 } }
