计算法
#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/86737656
https://blog.csdn.net/qq_41673920/article/details/86736722
等等