TS318_1B0814热电堆传感器在stm32上的应用

这次项目是工作中用到的一个内容,本人才疏学浅,如有遗漏,请大家多多指教

首先介绍一下TS318_1B0814热电堆传感器,这个传感器用到的资料我在百度云上传,简单说一下就是这是个模拟量传感器,要采集两路模拟信号,一路判断传感器自身温度,另一路结合传感器自身温度就能算出测量物体的温度。

链接:https://pan.baidu.com/s/13zDIR82lZlg7AHqSE7ha1A?pwd=awsl 
提取码:awsl

传感器电路图如下:

                                                                                  图1

下面是V1和R3两端代表Pin1和Pin3,放大倍数等于R5/R4(这里的放大倍数并不是最大,只是用了手边现有的电阻)

仿真电路

                                                                        图二

直流扫描结果

横坐标是V1,纵坐标是探针1

                                                                                图三

Cadence原理图

Header4 H2插传感器,H1接到开发板上供电,和接ad采集

                                                                            图四

做一个3cm*3cm的板板

PCB

                                                                   图五

stm32程序

c

#include "TS318_1B0814.h"
#include "delay.h" 
/*-------------|----------------   
		AD   PH4  <-> ADC3_INP15  红外温度          down
		AD   PH5  <-> ADC3_INP16  环境温度          up  		
-------------|----------------*/
float VTP_Value_Table[101]={-1.066,-1.028,-0.990,-0.952,-0.914,-0.874,-0.835,-0.795,-0.755,-0.714,-0.673,
														-0.631,-0.589,-0.546,-0.503,-0.46,-0.416,-0.372,-0.327,-0.282,
                            -0.236,-0.19,-0.143,-0.096,-0.048,0,0.049,0.098,0.147,0.197,
                            0.248,0.299,0.351,0.403,0.455,0.509,0.562,0.617,0.671,0.726,
                            0.782,0.839,0.895,0.953,1.011,1.069,1.128,1.188,1.248,1.309,
                            1.370,1.432,1.495,1.558,1.621,1.685,1.750,1.816,1.882,1.948,
                            2.015,2.083,2.152,2.221,2.290,2.360,2.431,2.503,2.575,2.648,
                            2.721,2.795,2.870,2.945,3.021,3.098,3.175,3.253,3.332,3.412,
                            3.492,3.572,3.654,3.736,3.819,3.902,3.986,4.071,4.157,4.243,
                            4.330,4.418,4.507,4.596,4.686,4.776,4.868,4.960,5.053,5.147,
                            5.241};//0-100度

float RNI1000_Value_Table[86]={1000.0,1005.5,1011.0,1016.5,1022.0,1027.6,1033.1,1038.7,1044.3,1049.9,
                               1055.5,1061.1,1066.8,1072.4,1078.1,1083.8,1089.5,1095.2,1100.9,1106.6,
                               1112.4,1118.1,1123.9,1129.7,1135.5,1141.3,1147.1,1153.0,1158.8,1164.7,
                               1170.6,1176.5,1182.4,1188.3,1194.2,1200.2,1206.1,1212.1,1218.1,1224.1,
                               1230.1,1236.1,1242.2,1248.2,1254.3,1260.4,1266.5,1272.6,1278.8,1284.9,
                               1291.1,1297.2,1303.4,1309.6,1315.8,1322.0,1328.3,1334.5,1340.8,1347.1,
                               1353.4,1359.7,1366.0,1372.4,1378.7,1385.1,1391.5,1397.9,1404.3,1410.8,
                               1417.2,1423.7,1430.1,1436.6,1443.1,1449.7,1456.2,1462.8,1469.3,1475.9,
                               1482.5,1489.1,1495.7,1502.4,1509.1,1515.7};//0-85度

float NTC_Value_Table[86]={332.59,315.83,300.02,285.09,270.98,257.66,245.07,233.17,221.29,211.26,
													 201.18,191.64,182.60,174.05,165.94,158.25,150.96,144.05,137.50,131.28,
													 125.37,119.76,114.44,109.38,104.57,100.0,95.65,91.52,87.59,83.84,
													 80.28,76.89,73.66,70.58,67.65,64.85,62.19,59.65,57.22,54.91,
													 52.70,50.60,48.58,46.66,44.83,43.07,41.40,39.79,38.26,36.80,
													 35.40,34.05,32.77,31.54,30.37,29.24,28.16,27.13,26.14,25.19,
													 24.28,23.40,22.57,21.76,20.99,20.25,19.54,18.86,18.21,17.58,
													 16.97,16.39,15.84,15.30,14.79,14.29,13.81,13.36,12.92,12.49,
													 12.08,11.69,11.31,10.95,10.60,10.26};											 
															 
															 
/*********************************************************************************************************
*	函 数 名: TS318_1B0814_Init
*	功能说明: TS318_1B0814红外测温传感器AD功能引脚初始化
*	形    参: 无
*	返 回 值: 无
*********************************************************************************************************/
void TS318_1B0814_Init(void)
{
	RCC->AHB4ENR|=1<<24;    		//使能ADC3时钟 
	RCC->AHB4ENR|=GPIOH_CLK;	//使能PORTC时钟
	GPIO_Set(GPIOH,PIN4|PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE);//PH4 PH5 模拟输入,不带上下拉
	RCC->AHB1RSTR|=1<<24;   		//ADC3复位
	RCC->AHB1RSTR&=~(1<<24);		//复位结束	
	RCC->D3CCIPR&=~(3<<16);		//ADCSEL[1:0]清零
	RCC->D3CCIPR|=2<<16;		  //ADCSEL[1:0]=2,per_ck作为ADC时钟源,默认选择hsi_ker_ck作为per_ck,频率:64Mhz
	ADC3_COMMON->CCR|=1<<18;	//PRESC[3:0]=1,输入时钟2分频,即adc_ker_ck=per_ck/2=64/2=32Mhz(不能超过36Mhz)

	ADC3->CR=0;   				    //CR寄存器清零,DEEPPWD清零,从深度睡眠唤醒.
	ADC3->CR|=1<<28;  			  //ADVREGEN=1,使能ADC稳压器
	delay_ms(10);				      //等待稳压器启动完成,约10us
	ADC3->CR|=1<<8;  			    //BOOST=1,ADC工作在boost模式(ADC频率大于20M的时候,必须设置boost位)	
	ADC3->CFGR&=~(1<<13);		  //CONT=0,单次转换模式
	ADC3->CFGR|=1<<12;			  //OVRMOD=1,复写模式(DR寄存器可被复写)	
	ADC3->CFGR&=~(3<<10);		  //EXTEN[1:0]=0,软件触发
	ADC3->CFGR&=~(7<<2);		  //RES[2:0]位清零
	ADC3->CFGR|=0<<2;			    //RES[2:0]=0,16位分辨率(0,16位;1,14位;2,12位;3,10位;4,8位.)

	ADC3->CFGR2&=~((u32)15<<28);   //LSHIFT[3:0]=0,不左移,数据右对齐.
	ADC3->CFGR2&=~((u32)0X3FF<<16);//OSR[9:0]=0,不使用过采样


	ADC3->CR&=~((u32)1<<30);	   //ADCALDIF=0,校准单端转换通道
	ADC3->CR|=1<<16;			       //ADCALLIN=1,线性校准
	ADC3->CR|=(u32)1<<31;		     //开启校准
	while(ADC3->CR&((u32)1<<31));//等待校准完成

	ADC3->SQR1&=~(0XF<<0);		//L[3:0]清零
	ADC3->SQR1|=0<<0;     		//L[3:0]=0,1个转换在规则序列中 也就是只转换规则序列1 

	ADC3->SMPR2&=~(7<<15);	      //通道15采样时间清空	  
	ADC3->SMPR2|=7<<15; 		      //通道15 810.5个周期,提高采样时间可以提高精确度	
	ADC3->SMPR2&=~(7<<18);	      //通道16采样时间清空	  
	ADC3->SMPR2|=7<<18; 		      //通道16 810.5个周期,提高采样时间可以提高精确度	
	
	ADC3->CR|=1<<0;	   			  //开启AD转换器	
}
/*********************************************************************************************************
*	函 数 名: Get_Adc3Value
*	功能说明: 获取ADC3指定通道的AD数值(16位,0-65535),10次采样,去除最大最小值取平均
*	形    参: Ch指定通道
*	返 回 值: 返回的AD数值
*********************************************************************************************************/
u16 Get_Adc3Value(u16 Ch) 
{
	u16 Data_Max,Data_Min,Data_Now,AD_Data;
	u8 i;
	u32 Data=0;
	ADC3->PCSEL|=1<<Ch;			    //ADC转换通道预选择 	  		 
	ADC3->SQR1&=~(0X1F<<6*1);	  //规则序列1通道清零
	ADC3->SQR1|=Ch<<6*1;		    //设置规则序列1的转换通道为ch 
	ADC3->CR|=1<<2;       		  //启动规则转换通道 
	while(!(ADC3->ISR&1<<2));	  //等待转换结束	 	   
	Data_Max=ADC3->DR;			    //返回adc值
	Data_Min=Data_Max;
	Data+=Data_Min;
	for(i=0;i<9;i++)
	{
		ADC3->PCSEL|=1<<Ch;			    //ADC转换通道预选择 	  		 
		ADC3->SQR1&=~(0X1F<<6*1);	  //规则序列1通道清零
		ADC3->SQR1|=Ch<<6*1;		    //设置规则序列1的转换通道为ch 
		ADC3->CR|=1<<2;       		  //启动规则转换通道 
		while(!(ADC3->ISR&1<<2));	  //等待转换结束
		Data_Now=ADC3->DR;
		if(Data_Max<Data_Now)
			Data_Max=Data_Now;
		if(Data_Min>Data_Now)
			Data_Min=Data_Now;
		Data+=Data_Now;
	}
	Data=Data-Data_Min-Data_Max;
	AD_Data=Data/8;
	return AD_Data;
}
/*********************************************************************************************************
*	函 数 名: Caculate_T_sensor
*	功能说明: 输入电阻值,根据线性插补,算出传感器温度
*	形    参: float value
*	返 回 值: 一般应该会在0-85度
*********************************************************************************************************/
float Caculate_T_sensor(float value,u8 sensor)
{
	float T_sensor;
	
	if(sensor==0)
	{
		if(value<=RNI1000_Value_Table[0])
		{
			return 0;
		}
		if(value>=RNI1000_Value_Table[85])
		{
			return 85;
		}
		for(int i =0;i<86;i++)
		{
			if((value>RNI1000_Value_Table[i])&&(value<RNI1000_Value_Table[i+1]))
			{
				T_sensor=(value-RNI1000_Value_Table[i])/(RNI1000_Value_Table[i+1]-RNI1000_Value_Table[i])+i;
				return T_sensor;
			}
		}
		return -1;
	}
	
	
	
	if(sensor==1)
	{
		if(value<=NTC_Value_Table[0])
		{
			return 0;
		}
		if(value>=NTC_Value_Table[85])
		{
			return 85;
		}
		for(int i =0;i<86;i++)
		{
			if((value>NTC_Value_Table[i])&&(value<NTC_Value_Table[i+1]))
			{
				T_sensor=(value-NTC_Value_Table[i])/(NTC_Value_Table[i+1]-NTC_Value_Table[i])+i;
				return T_sensor;
			}
		}
  	return -1;
	}
	
}
/*********************************************************************************************************
*	函 数 名: Caculate_Voffs
*	功能说明: 输入温度,根据线性插补,算出电压
*	形    参: float value
*	返 回 值: Voffs
*********************************************************************************************************/
float Caculate_Voffs(float value)
{
	float Voffs;
	for(int i=0;i<101;i++)
	{
		if(value>=i&&value<i+1)
		{
			
			float k ,b;
			k=VTP_Value_Table[i+1]-VTP_Value_Table[i];
			b=VTP_Value_Table[i]-k*i;
			Voffs=k*value+b;
			return Voffs;
		}
	}
	return -1;
}
/*********************************************************************************************************
*	函 数 名: Caculate_T_object
*	功能说明: 输入电压,根据线性插补,算出温度
*	形    参: float value
*	返 回 值: 0-100范围内的温度
*********************************************************************************************************/
float Caculate_T_object(float value)
{
	float T_object;
	for(int i=0;i<101;i++)
	{
		if((value>VTP_Value_Table[i])&&(value<VTP_Value_Table[i+1]))
		{
			T_object=(value-VTP_Value_Table[i])/(VTP_Value_Table[i+1]-VTP_Value_Table[i])+i;;
			return T_object;
		}
	}
	return -1;
}
/*********************************************************************************************************
*	函 数 名: Get_temperature
*	功能说明: 计算物体温度,太低可能监测不出来,这时候可以修改Sconv,
*	形    参: 	 
*	说    明:
                            1号	    2号
                   Sconv	0.1385	0.1335
              237行常数项	  5.8    -4.8
*	返 回 值: 0-100范围内的温度
*********************************************************************************************************/
float Get_temperature(void)
{
	float Sconv=0.1335;
	u16 Adc3_15=Get_Adc3Value(15);
	u16 Adc3_16=Get_Adc3Value(16);
	float temp_sen_volt=3.28*Adc3_16/65536; 
	float R_ni1000=1000*temp_sen_volt/3.28f/(1-temp_sen_volt/3.28f);     //rni1000电阻值
	float T_sensor=Caculate_T_sensor(R_ni1000,0)-4.8f;                     //计算传感器温度
		
	float Vtp=1000*(3.28f*Adc3_15/65536-1.26f)/(313.65f);    //放大前值,单位mv
	
	float Vtpc=(Vtp)/Sconv;
		
	float Tcf=1-((T_sensor-25)*0.0045f);
		
	float Voffs=Caculate_Voffs(T_sensor);           //第一次调用
		
	float Voffs_tc=Voffs*Tcf;   
			
	float Vtp_ref=Vtpc+Voffs_tc;   
			
	float Vtp_ref_tc=Vtp_ref/Tcf;
		
	float T_object=Caculate_T_object(Vtp_ref_tc);   //第二次调用
	
	return T_object;
}

h

#ifndef __TS318_1B0814_H
#define __TS318_1B0814_H

#include "sys.h" 
void TS318_1B0814_Init(void);

u16 Get_Adc3Value(u16 Ch);

float Caculate_T_sensor(float value ,u8 sensor);

float Caculate_Voffs(float value);

float Caculate_T_object(float value);

float Get_temperature(void);
#endif

用的时候在main里面用初始化和最后一个就可以了。移植的话需要考虑你的adc用的和我不一样,要去查数据手册。

最后说一下

计算过程

(全部来自于泰科官网一份pdf资料)

1环境温度

                                                                         表一

拿到从传感器之后,用万用表电阻档接2、4,室温下1100多欧姆就是正常的,这个电阻随温度上升而上升,很线性

                                                                                图六

                                                                           表二

用分压电路去测这个电阻值就可以。

2环境温度校准

计算得到传感器温度之后,看一下这个传感器温度准不准,可以用一个比较准的温度传感器,把热电堆和它放一起,差值就是常数项。

3计算物体温度

通常一个产品中热电堆和测量物体之间的相对位置是确定的,而且不同产品中 它们的相对位置也不同,经过测量,在同一组参数下,热电堆越靠近被测物体,测得温度越大。所以要固定一个距离,保持传感器为25度时,查看测得的原始电压值VTP1(mv),

                                                                                表三

VTPC=VTP/(VTP1/5.241f)

计算依据如下

                                                                                图七

之后按照下面的步骤计算就可以了

                                                                                 图八

有几个需要说明的地方,首先是Vtp是通过ad读取到的16位数值(最大65535)算出来的,参考前面mutisim的曲线,然后这里的LUT和RLUT就是参考表二,搞一下线性插值。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值