单片机_NTC精准读取温度

单片机_NTC精准读取温度

前言:给客户做的一个PID温控系统,采集温度的传感器就是使用NTC,结果控制效果极不稳定,调试好几个星期才确定是因为温度采集的不稳定导致的,所以仔细研究了NTC读取的方式,一般都采用查表法(想实现高精度不太容易),我的方法是采用数学模型采用函数计算的方式,这样就可以实现无极变速的那种精度。
核心思想:把电阻值与温度的曲线细分成无数段直线
在这里插入图片描述
我的NTC型号:
在这里插入图片描述
在这里插入图片描述

ntc.h

#ifndef __NTC_H_
#define __NTC_H_

#include "lib/STC15X.h"

void ntc_init();
float OneDimensionalEquation(uint32 x1,uint32 y1,uint32 x2,uint32 y2,uint32 Unkown_x,uint32 Unkown_y);
float Res_To_Temperature(uint32 NTC_Res);
uint32 Count_Ntc_R(void);
#endif

ntc.c

#include "ntc.h"
#include "lib/STC15_ADC.h"
#include "delay.h"
#include <stdio.h>

#define  NTC_ADC_PIN    ADC_P10

//X_Temp与Y_Res一一对应的关系
code uint32 X_Temp[91] = 
{
-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
};

code uint32 Y_Res[91]=
{
55800,52851,50074,47457,44987,42657,40456,38376,36412,34555,		//-10~-1
32800,31140,29572,28090,26689,25366,24116,22935,21820,20767,19773,	//0~10
18834,17949,17112,16323,15577,14873,14208,13578,12983,12419,		//11~20
11884,11377,10895,10437,10000,9513,9064,8648,8263,7904,				//21~30
7569,7255,6960,6682,6419,6170,5932,5706,5490,5283,					//31~40
5085,4895,4712,4536,4366,4203,4046,3895,3750,3610,					//41~50
3475,3345,3221,3101,2986,2876,2770,2669,2572,2480,					//51~60
2391,2306,2225,2148,2074,2003,1935,1871,1809,1750,					//61~70
1693,1638,1585,1535,1486,1439,1393,1348,1304,1261 					//71~80
};

void ntc_init()  //初始化ADC
{
    adc_init(NTC_ADC_PIN, ADC_540T, ADC_10BIT);
}

//输入两个坐标,计算出两点之间的直线方程,然后就可以输入该直线上任意一点的Y坐标(根据ADC的值换算出电阻值)而得到X坐标(温度值)
float OneDimensionalEquation(uint32 x1,uint32 y1,uint32 x2,uint32 y2,uint32 Unkown_x,uint32 Unkown_y)
{
	float k = 0;
	float b = 0;
	
	k = ((float)y1-(float)y2)/((float)x1-(float)x2);
	b = (float)y1-(float)x1*k;
	
	if(0 == Unkown_x)
		return ((float)Unkown_y-b)/k;
	else
		return ((float)Unkown_x*k+b); 
}

//输入电阻值,获取到温度
float Res_To_Temperature(uint32 NTC_Res)
{
	uint8 Loop = 0;
	uint8 StartPoint = 0;
	float RealTemp = 0;
	
	for(Loop = 0;Loop < 91;Loop++)
	{
		if(NTC_Res > Y_Res[Loop])
		{
			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;
}

uint32 Count_Ntc_R(void)  //读取ADC的值
{
	uint32 ntc_r;
	uint32 adc;
	adc = adc_read(NTC_ADC_PIN);
	ntc_r = (10000*adc)/(1024-adc);
	return ntc_r;
}

我的项目实践:
在这里插入图片描述

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值