pt 100热敏pt100电阻与温度换算如何转换为温度曲线?

引言在做智能家居的项目中,经常会遇到对温度的测量,温度是自然界中一个最要的物理参数。无论是在各种实验场所,还是居住休闲场所,还是工业生产场所,温度的采集和控制都十分频繁和重要。所以温度传感器便显得十分重要,PT100便是其中一员。PT100是一种正温度系数的热敏电阻。【随着温度的升高,电阻的阻值变大,就是正温度系数的热敏电阻,相反,如果随着温度的升高,电阻的阻值变小,就是负温度系数的热敏电阻。】PT100热电阻因制造的工艺不同,其测温范围亦有不同,陶瓷铂热电阻,可以测量的温度范围最广,-200~800℃,现在已经可以到-250~850℃。云母铂热电阻,由于云母的特性,其测温范围是-200~420℃。薄膜铂热电阻由于其封装及制造特性,其测温范围是-50~500℃。PT100之所以应用很广泛,不仅是因为它可以测的温度范围宽(零下几十度到零上几百度),还因为它的线性度非常好。“线性度”,说的直白一点就是温度每变化一度,电阻的阻值升高的幅度是基本相同的。由于PT100热电阻的温度与阻值之间的关系,人们便利用它的这一特性用来测量温度。PT100常规测量方法常规使用PT100测量温度基本原理是,电流流过PT100,输出电压然后使用ADC测得电压,因为V=IR,如果电流恒定,则电压与电阻值成正比,从而测得温度。例如网上常见的一个P100电压采集放大电路:该电路输出的电压范围为0.3-3.3V。前半部分是4.096V恒压源电路,然后是一个桥式电压采样电路,后面是一个电压放大电路。电桥电压为TL431产生的基准电压4.096V。R9和R10作为电桥的两臂,电桥输入送到由运放组成的放大电路中,经过放大后输出电压值由单片机检测。但是这种方法有诸多限制,比如TL431精度,运放温漂,运放放大倍数的调节用以适应3.3V单片机和5V单片机,以及单片机ADC采集精度等,都会造成对温度测量的误差。2. 通过频率测量温度的方法现在提出一种新的测量方法,设计了一种电路让输出频率与电阻值成正比关系,即F=KR(式中F为频率,K为常数,R为电阻值),通过测量频率从而得到PT100的阻值,根据阻值与温度的关系最终测得温度,而对频率的测量只需要单片机有定时器和中断即可,而这是单片机基本上都有的资源(采用ADC测量受限于有的单片机不一定有ADC)。该测量电路如下:基于RC振荡器的温度测量电路该电路优点:RC振荡电路将模拟量阻值转换为数字量频率(周期)、不使用AD口、无需放大电路、成本低廉、实用性强。测量原理:电路是一个由LM393(U2-A)组成的RC振荡器。LM393 是一款双电压比较器集成电路。电压比较器的功能是用于比较两个电压的大小,其特性如下:①当“+”同向输入端电压高于“-”反向输入端时,电压比较器输出为高电平;②当“+”同向输入端电压低于“-”反向输入端时,电压比较器输出为低电平。由单片机测量RC震荡回路的频率f,然后根据标准电容C1【原理图中的C45】得出PT100的阻值R1。该电路工作过程如下:上电后LM393引脚1电平V1=Vcc,引脚3电平引脚2电平初始为0,上电后V3>V2,所以PIN1电平V1为高电平。V1通过R1给C45充电逐渐升高,当引脚2电平V2大于引脚3电平V3,引脚1电平变为低电平,引脚3电平:引脚1电平变为低电平之后,引脚2电平V2由电容C45通过R1开始放电。当引脚2电平V2放电到小于引脚3电平V3,引脚1电平变为Vcc。由此,往复循环形成振荡输出一个周期性的方波。根据RC充放电工作计算可得,占空比Duty Ratio周期T即,该电路输出的是一个周期为1.386RC,占空比为50%的方波。测量时选用容值固定精度较高的标称电容,由此测得周期与PT100的阻值成正相关,从而得到温度。3. 实测波形LM393 PIN2实测波形LM393 PIN3实测波形LM393 PIN1实测波形(输出波形),注意这个引脚接单片机带中断功能的IO口。PIN1(蓝线)和PIN2(黄线)实测波形。与分析相合,PIN2为一个指数波形。幅值约为输出的1/3到2/3。PIN1(蓝线)和PIN3(黄线)实测波形。PIN3幅值约为PIN1输出的1/3到2/3。评论区提问有说到精度问题,可参阅如下这个网页:High-res Cap meter by RomanBlack参考:漫谈PT100测温电路经验
计算法
#include "math.h"
//Rt = R *EXP(B*(1/T1-1/T2))
//caculta T1
//10K 电阻串ntc,ntc接vcc端
const float Rp=10000.0; //10K
const float T2 = (273.15+25.0);//T2
const float Bx = 3950.0;//B
const float Ka = 273.15;
float Get_Temp(uint16_t NTC_Res)
{
float Rt;
float temp;
Rt = NTC_Res;
//like this R=5000, T2=273.15+25,B=3470, RT=5000*EXP(3470*(1/T1-1/(273.15+25)),
temp = Rt/Rp;
temp = log(temp);//ln(Rt/Rp)
temp/=Bx;//ln(Rt/Rp)/B
temp+=(1/T2);
temp = 1/(temp);
temp-=Ka;
return temp;
}
#include "math.h"
#define B 3950.0//温度系数
#define TN 298.15//额定温度(绝对温度加常温:273.15+25)
#define RN 10// 额定阻值(绝对温度时的电阻值10k)
#define BaseVol 5.04 //ADC基准电压
//10K电阻串ntc,ntc接gnd端
float Get_Tempture(u16 adc)
{
float RV,RT,Tmp;
RV=BaseVol/1024.0*(float)adc;//ADC为10位ADC,求出NTC电压:RV=ADCValu/1024*BaseVoltag
RT=RV*10/(BaseVol-RV);//求出当前温度阻值 (BaseVoltage-RV)/R16=RV/RT;
Tmp=1/(1/TN+(log(RT/RN)/B))-273.15;//%RT = RN exp*B(1/T-1/TN)%
return Tmp;
}
双表法
#include <stdio.h>
/*10K NTC 温度与阻值对应表 X轴代表温度
Y轴代表阻值*/
uint16_t X_Temp[17] = {0,6,12,18,25,31,37,45,50,57,63,70,76,83,89,94,100};
uint16_t Y_Res[17] = {31908,23698,17794,13498,9900,7625,5925,4288,3529,2709,2177,1701,1386,1101,909,778,649};
/*************************************************
*函数名称:OneDimensionalEquation
*功
能:解一元一次方程
给出两点坐标和第三点的x值或y值
得出第三点y值或x值
*参
数:
*返 回 值:
*************************************************/
float OneDimensionalEquation(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t Unkown_x,uint16_t Unkown_y)
{
float k = 0;
float b = 0;
k = (((int32_t)y1-(int32_t)y2)/((int32_t)x1-(int32_t)x2));
b = y1-x1*k;
if(0 == Unkown_x)
//如果unknown_x设为0 就是求x的值 否则求y值
return ((float)Unkown_y-b)/k;
else
return ((float)Unkown_x*k+b);
}
/*************************************************
*函数名称:uint8_t Res_To_Temperature(uint16_t NTC_Res)
*功
能:计算真实温度
*参
数:NTC当前阻值
*返 回 值:温度值
*************************************************/
float Res_To_Temperature(uint16_t NTC_Res)
{
uint8_t Loop = 0;
uint8_t StartPoint = 0;
float RealTemp = 0;
/*查找阻值所对应的区间*/
for(Loop = 0;Loop < 17;Loop++)
{
if(NTC_Res > Y_Res[Loop+1])
{
StartPoint = Loop;
break;
}
}
RealTemp = (float)OneDimensionalEquation(X_Temp[StartPoint],Y_Res[StartPoint],X_Temp[StartPoint+1],Y_Res[StartPoint+1],0,NTC_Res);
return RealTemp;
}
双表法2一表记录温度值,一表记录对应的AD值,方法与上面的类似。#define NTC_TABLE 11//温度取点个数
const s32 Ntc_Tempc[NTC_TABLE]= {-2000, -1000,
0, 1000, 2000, 3000,
4000,
5000,
6000,
7000,
8000};//各个点对应的温度值,两位小数
const s32 Ntc_val[NTC_TABLE]=
{51064, 49650, 47527,44546,40672, 36042,
30950, 25803, 20977, 16722, 13167}; //各个点对应的AD值
void calcu_envtemp(AD_PARA* adpara)//温度计算
{
u8 i;
s32 a = 0;
s32 temp = 0;
//计算当前的环境温度【16位AD;3.3V系统】
if (adpara->SAMPVAL < Ntc_val[NTC_TABLE-1])//温度值限制在80度以内
{
adpara->CLVAL = 8000;
ALARM_SIG.ENVTempSpill_SIG = 1;//温度溢出标志
}else if(adpara->SAMPVAL > Ntc_val[0])
{
adpara->CLVAL = -2000;
ALARM_SIG.ENVTempSpill_SIG = 1;//温度溢出标志
}else if((adpara->SAMPVAL <= Ntc_val[0])&&(adpara->SAMPVAL >= Ntc_val[NTC_TABLE-1]))
{
ALARM_SIG.ENVTempSpill_SIG = 0;//温度溢出标志
for (i = 0; i < NTC_TABLE-2; i++)
{
if (adpara->SAMPVAL >= Ntc_val[i + 1])
{
temp = (s32)adpara->SAMPVAL - Ntc_val[i];
a = temp * (Ntc_Tempc[i+1] - Ntc_Tempc[i]);
temp = a / (Ntc_val[i+1] - Ntc_val[i]);
adpara->CLVAL = temp + Ntc_Tempc[i];
break;
}
}
adpara->CLVAL+= (UTempPARA.ENVTAmendPARA*10);//校正偏差
}
}
/*
代码中:
adpara->SAMPVAL为ADC采样值
adpara->CLVAL为计算得到温度值
*/
单表查询/*
*********************************************************************************************************
*
* 模块名称 : ntc热敏电阻
* 文件名称 : bsp_ntc.c
* 版
本 : V1.0
* 说
明 : 测温,常用
*
* 修改记录 :
*
版本号
日期
作者
说明
*
V1.0 2019-07-17

*********************************************************************************************************
*/
#include "bsp.h"
#define TAB_NUM
101
/*数组是使用MCU超级工具计算的电压和温度对应值*/
const unsigned int temptab[]={
//0 to 100℃ step 1
10个数一行
3038,3001,2964,2927,2889,2851,2812,2773,2734,2694,
2654,2614,2574,2533,2493,2452,2411,2371,2330,2289,
2249,2208,2168,2128,2088,2048,2009,1969,1931,1892,
1854,1816,1779,1742,1706,1670,1634,1599,1564,1530,
1497,1464,1431,1399,1368,1337,1307,1277,1248,1219,
1191,1164,1137,1110,1085,1059,1034,1010,986,963,
941,918,897,876,855,835,815,796,777,759,
741,723,706,689,673,657,642,627,612,598,
584,570,557,544,531,519,507,495,484,473,
462,452,441,431,422,412,403,394,385,376,
368,
};
/*
********************************************************************************************************
* 函 数 名: bsp_ntcTemp
* 功能说明: 返回电压对应的温度值
* 形
参:
u16NtcRegisterValue:滤波后,NTC ADC寄存器的值
* 返 回 值: 温度值
返回127是温度不在数组范围内
********************************************************************************************************
*/
static int8_t bsp_ntcTemp(uint16_t u16NtcRegisterValue)
{
uint8_t i;
uint16_t a,b;
//温度是否等于第一个数组值得温度
a = (temptab[0] - temptab[1])/2;
a = temptab[0] - a;
if((u16NtcRegisterValue>=a) && (u16NtcRegisterValue<=temptab[0]))
{
return 0;
}
//温度是否等于最后一个数组值得温度
a = (temptab[TAB_NUM-2] - temptab[TAB_NUM-1])/2;
a = temptab[TAB_NUM-1] + a;
if((u16NtcRegisterValue<=a) && (u16NtcRegisterValue>=temptab[TAB_NUM-1]))
{
return TAB_NUM-1;
}
/*第一个和最后一个数组值不适合下面这个算法*/
for (i = 1; i < (TAB_NUM-2); i++)
{
/*数据取一个范围值*/
a = (temptab[i] - temptab[i+1])/2;
b = (temptab[i-1] - temptab[i])/2;
a = temptab[i] - a; //往温度高的方向(数值低)
b = temptab[i] + b; //往温度低的方向(数值高)
if((u16NtcRegisterValue>=a) && (u16NtcRegisterValue<=b))
{
return i;
}
}
return 127;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 获取NTC1的温度
* 形
参:无
* 返 回 值: 温度值
*********************************************************************************************************
*/
int8_t
app_getNtc1Temp(void)
{
int8_t i8Temp;
i8Temp = bsp_ntcTemp(bsp_getAdcRegister_ToBlock(20,5));
return i8Temp;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_Init
* 功能说明: 获取NTC2的温度
* 形
参:无
* 返 回 值: 温度值
*********************************************************************************************************
*/
int8_t
app_getNtc2Temp(void)
{
int8_t i8Temp;
i8Temp = bsp_ntcTemp(bsp_getAdcRegister_ToBlock(20,6));
return i8Temp;
}
单表差值//ntc接gnd端
//NTC的ad值对应表
static u16 NTCTAB[241]=
{
0xFED
,0xFE2
,0xFD6
,0xFCB
,0xFBF
,0xFB3
,0xFA6
,0xF9A
,0xF8D
,0xF80,
0xF73
,0xF65
,0xF58
,0xF4A
,0xF3B
,0xF2D
,0xF1E
,0xF0F
,0xF00
,0xEF1,
0xEE1
,0xED1
,0xEC1
,0xEB1
,0xEA0
,0xE8F
,0xE7E
,0xE6C
,0xE5B
,0xE49,
0xE37
,0xE24
,0xE12
,0xDFF
,0xDEC
,0xDD9
,0xDC5
,0xDB1
,0xD9D
,0xD89,
0xD75
,0xD60
,0xD4B
,0xD36
,0xD21
,0xD0B
,0xCF6
,0xCE0
,0xCCA
,0xCB4,
0xC9D
,0xC87
,0xC70
,0xC59
,0xC42
,0xC2B
,0xC14
,0xBFC
,0xBE4
,0xBCD,
0xBB5
,0xB9D
,0xB85
,0xB6C
,0xB54
,0xB3C
,0xB23
,0xB0A
,0xAF2
,0xAD9,
0xAC0
,0xAA7
,0xA8E
,0xA75
,0xA5C
,0xA43
,0xA2A
,0xA11
,0x9F8
,0x9DF,
0x9C6
,0x9AD
,0x994
,0x97B
,0x962
,0x949
,0x930
,0x917
,0x8FE
,0x8E5,
0x8CC
,0x8B4
,0x89B
,0x882
,0x86A
,0x852
,0x839
,0x821
,0x809
,0x7F1,
0x7D9
,0x7C2
,0x7AA
,0x793
,0x77B
,0x764
,0x74D
,0x736
,0x720
,0x709,
0x6F3
,0x6DC
,0x6C6
,0x6B0
,0x69B
,0x685
,0x670
,0x65A
,0x645
,0x630,
0x61C
,0x607
,0x5F3
,0x5DE
,0x5CB
,0x5B7
,0x5A3
,0x590
,0x57D
,0x569,
0x557
,0x544
,0x532
,0x51F
,0x50D
,0x4FB
,0x4EA
,0x4D8
,0x4C7
,0x4B6,
0x4A5
,0x495
,0x484
,0x474
,0x464
,0x454
,0x444
,0x435
,0x425
,0x416,
0x407
,0x3F9
,0x3EA
,0x3DC
,0x3CD
,0x3BF
,0x3B2
,0x3A4
,0x397
,0x389,
0x37C
,0x36F
,0x363
,0x356
,0x34A
,0x33D
,0x331
,0x325
,0x31A
,0x30E,
0x303
,0x2F8
,0x2EC
,0x2E2
,0x2D7
,0x2CC
,0x2C2
,0x2B7
,0x2AD
,0x2A3,
0x299
,0x290
,0x286
,0x27D
,0x273
,0x26A
,0x261
,0x258
,0x250
,0x247,
0x23F
,0x236
,0x22E
,0x226
,0x21E
,0x216
,0x20E
,0x206
,0x1FF
,0x1F8,
0x1F0
,0x1E9
,0x1E2
,0x1DB
,0x1D4
,0x1CD
,0x1C7
,0x1C0
,0x1BA
,0x1B3,
0x1AD
,0x1A7
,0x1A1
,0x19B
,0x195
,0x18F
,0x18A
,0x184
,0x17E
,0x179,
0x174
,0x16E
,0x169
,0x164
,0x15F
,0x15A
,0x155
,0x150
,0x14C
,0x147,
0x142
,0x13E
,0x139
,0x135
,0x131
,0x12C
,0x128
,0x124
,0x120
,0x11C,
0x118
};
//查表函数
u8 look_up_table(u16 *a,u8 ArrayLong,u16 data)
{
u16 begin,end,middle ;
u8 i ;
begin = 0 ;
end = ArrayLong-1 ;
i = 0
;
if(data >= a[begin]) return begin ;
else if(data <= a[end]) return end ;
while(begin < end)
{
middle = (begin+end)/2 ;
if(data == a[middle] ) break ;
if(data < a[middle] && data > a[middle+1]) break ;
if(data > a[middle])
end = middle ;
else begin = middle ;
if(i++ > ArrayLong) break ;
}
if(begin > end ) return 0 ;
return middle ;
}
//输入表的序号值,得到温度值
float num_to_temperature(u8 num)
{
float
data;
data = 0.5*num-20;
return data;
}
插值
if( (data<=NTCTAB[0]) && (data>NTCTAB[240]) )
{
num=look_up_table(NTCTAB,241,data);
t1=num_to_temperature(num);
tx=0.5*(data-NTCTAB[num])/(NTCTAB[num+1]-NTCTAB[num])+t1;
printf("temp_ntc:%4.2f\r\n",tx);
}
参考https://blog.csdn.net/qq_41673920/article/details/86737656https://blog.csdn.net/qq_41673920/article/details/86736722等等

我要回帖

更多关于 pt100电阻与温度换算 的文章