锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

mst358 温控(热敏电阻)调试

时间:2023-01-04 03:30:01 ln9t25ic集成电路ncp1271集成电路ic

参考:https://blog.csdn.net/kehyuanyu/article/details/103178926

硬件电路:
在这里插入图片描述

硬件上有两个热敏电阻ADC1和ADC收集温度信息。ADC3.测量光机温度。温度和电阻的对照表参考村田热敏电阻NCP15WF104F03RC.pdf》;ADC1是DMD位置主板上的对照表参考热敏电阻100k_3950_101203.xls》。

PhoneWindowManager.java有添加接口读取adc值的。这里已经调试过了ADC以获得光机温度为例:

ADC如何将读取的电压值转换为热敏电阻电压值和热敏电阻温度值?
根据上述电路,热敏电阻和R250串联,对3.3V(实测3.317V)分压,热敏电阻两端电压U=3.3*Rw/(R250 Rw)。当外部温度发生变化时,主芯片通过ADC3(SAR3)收集变化电压值,反转当前温度。

SAR3引脚配置
E4 的pin 脚定义:
mst358\vendor\mstar\mboot\MBoot\sboot\inc\mainz\board\chip\MSD93AEGM8.h

SAR3 口定义:
mst358\vendor\mstar\mboot\MBoot\sboot\inc\mainz\board\BD_MST142B_10A_MAINZ.h

mboot 定义好sar三口后,可以使用以下接口获取adc 值了。

//------------------------------------------------------------------------------------------------- /// Set SAR as ADC channel. /// @ingroup G_SAR_COMMON /// @param u8Channel: sar ADC channel 0~7 /// @param bEnable: 1: configured as ADC, 0: configured as GPIO input /// @return E_SAR_ADC_OK: Success /// @return E_SAR_ADC_FAIL or other values: Failure //------------------------------------------------------------------------------------------------- SAR_AdcResult MDrv_SAR_Adc_Config(MS_U8 u8Channel,MS_BOOL bEnable);  //------------------------------------------------------------------------------------------------- /// Get ADC value function for each SAR channel. /// @ingroup G_SAR_COMMON /// @param u8Channel: sar ADC channel 0~7 /// @return MS_U8: ADC value //------------------------------------------------------------------------------------------------- MS_U8 MDrv_SAR_Adc_GetValue(MS_U8 u8Channel); 

mboot和kernel可直接使用MDrv_SAR_Adc_GetValue()获取某个通道ADC值,注意只能返回8-bit的值。对于SAR 3 ,直接使用MDrv_SAR_Adc_GetValue(3)来获取ADC值。有了ADC 下一步需要与温度建立函数关系。

热敏电阻的电阻值
由于热敏电阻是可变电阻,我们需要在计算温度之前测量电阻,但我们不能直接测量电阻,只能测量电压。分压器的公式是:


就热敏电阻电路中的分压器而言,上述等式的变量为:

这个等式可以重新排列和简化来解决R2.即热敏电阻的电阻:
R2=(R1*Vout)/(Vin-Vout)

带入本项目的电路R1=10K,Vin=3.3V,Vout由SAR 3 采集。即:
R2=(10K x Vout )/(3.3V- Vout)。

温度计算,Steinhart-Hart方程和B值法
参考:
https://baijiahao.baidu.com/s?id=1620021463882312794&wfr=spider&for=pc
https://wenku.baidu.com/view/e2f53c4c2f3f5727a5e9856a561252d380eb2092.html
https://blog.csdn.net/kezunhb/article/details/86631695

使用Steinhart-Hart将热敏电阻的电阻值转换为温度读数的方程或B值计算方法。

  • Steinhart-Hart方程计算法:
    1/T = A B?ln? C?[ln?]
    这里: T 为绝对温度K(开尔文温度),R 单位是欧姆

  • 温度系数B值计算法:
    R = R(25℃)?exp[B?(1/T - 1/298.15)]
    这里: T 为绝对温度K(开尔文温度),R(25℃) 是热敏电阻 25℃时的阻值 (单位为Ω)

  • C语言实现的温度计算公式
    Tsteinhart = 1/(A Blog(Rth) Cpow(log(Rth),3))-273.15;
    Tbeta = 1/(1/(273.15 25) 1/Beta*log(Rth/R25))-273.15;

以下是温度系数B值计算法。NCP15WF104F03RC.pdf》中有:

也就是说,25度,R25=100K,Beta根据实际应用场景选择常数,这里我们选择25度~85度,即Beta=代入公式4311:
Tbeta = 1/(1/(273.15 25) 1/4311log(Rth/(100K)))-273.15
= 1/(1/298.15 1/4311
log(Rth/(100K)))-273.15

注:
温度系数计算: NTC热敏电阻计算器V1.0
https://www.etdev.net/data/attachment/forum/201901/nc_calculator/

NTC热敏电阻计算器使用方法:https://www.etdev.net/thread-104-1-1.html
用上面的工具,计算得到Beta=4200,这个值算出来的温度更加接近于《村田热敏电阻NCP15WF104F03RC.pdf》映射表的值。

ln、log、lg在数学公式中和c语言中的区别:
参考:http://www.cplusplus.com/reference/cmath/
数学中log是对数符号,右边写真数和底数(上面是真数,下面是底数)lg是以10为底数(例lg100=2)(lg为常用对数)ln是以e为底数(lne2=2)(ln为自然对数 e=2.718281828459045…)
c语言里面只有两个函数log和log10,其中函数 log(x) 表示是以e为底的自然对数,即 ln(x)函数。 log10(x) 以10为底的对数,即 lg(x)。以其它数为底的对数用换底公式来表示:loga(b)=ln(b)/ln(a),C语言表示成log(b)/log(a)。

C代码实现(示例)

//电压换算成温度
int temp_data(void)
{ 
       
   float temp=0;
   float Rth=0;
   float R25=100000;
   float T25=273.15+25;
   float Beta=4200;
   float Ka=273.15;
   float vol=(float)((Get_Adc_Average())*(3.3/255));
   Rth=(10000*vol)/(3.3-vol);	//10000kΩ is R249 value
   temp=1/(1/T25+log(Rth/R25)/Beta)-Ka+0.5;	//+0.5是误差矫正
   return temp;
}

Java代码中的实现(示例)

    private short mOldAdcValueDMD=0;
	private short mDMDTemperatureValue=0;
	private short getDMDTemperature(short adcValue){ 
       
		if(adcValue == mOldAdcValueDMD
			|| adcValue == (mOldAdcValueDMD - 1)
			|| adcValue == (mOldAdcValueDMD + 1)){ 
       
			return mDMDTemperatureValue;
		}

		short DMDtemp = 0;
		float Rth=0;
		float R25=100000;
		float T25=(float)273.15+25;
		float Beta=3950;
		float Ka=(float)273.15;
		float vol=(float)(adcValue*(3.3/255));
		Rth=(float)((10000*vol)/(3.3-vol));		//10000kΩ is R249 value
		DMDtemp=(short)(1/(1/T25+MathUtils.log(Rth/R25)/Beta)-Ka+0.5);	//+0.5是误差矫正

		mDMDTemperatureValue=(short)DMDtemp;
		mOldAdcValueDMD = adcValue;

		return mDMDTemperatureValue;
    }

然后,按照上面的方法集成了软件,但发现硬件上如论怎么测量,光机温度SAR3检测电压一直为3.3V,而SAR1检测电压是有变化的。让硬件分析,回复说光机内部不是使用热敏电阻(硬件需要修改:去掉上拉电阻R250、贴R800为0Ω),而是使用了S-5813A/5814A系列温度传感器IC,规格书参考《S5813A_5814A_E.pdf》。。这款芯片的内部原理可能是将热敏电阻的电压转换为线性输出的电压值了:

Ta = -30°C: 2.582 V典型值
Ta = +30°C: 1.940 V典型值
Ta = +100°C: 1.145 V典型值

Y=ax+b
2.582=a*(-30)+b
1.940=a*(30)+b
1.145=a*(100)+b

第1、2计算得到:
A=-0.0107
B=2.261

第2、3计算得到:
a=-0.011356
b=2.2806

第1、3计算得到:
A=-0.011054
B=2.2504

因为S-5813A转换出来的电压值也不是完全线性的,为降低误差,这里分两个区间来计算温度:
第一个区间是-30°~30°,Vol=-0.0107Ta+2.261,则Ta=(2.261-Vol)/0.0107
第二个区间是30°~100°,Vol=-0.011356
Ta+2.2806,则Ta=(2.2806-Vol)/0.011356
Java代码中的实现(示例)

	private short mOldAdcValueRay=0;
	private short mRayTemperatureValue=0;
	private short getRayTemperature(short adcValue){ 
       
		if(adcValue == mOldAdcValueRay){ 
       
			return mRayTemperatureValue;
		}

		float vol=(float)(adcValue*(3.3/255));
		if(vol > 2.6)
			return mRayTemperatureValue;
		else if(vol < 1.150)
			return mRayTemperatureValue;

		float Raytemp = 0;
		if(vol < 1.940){ 
       	//30°~100°
			Raytemp = (float)((2.2806-vol)/0.011356);
		}else{ 
       	//-30°~30°
			Raytemp = (float)((2.261-vol)/0.0107);
		}
		Log.d(TAG, "getRayTemperature() adcValue="+adcValue+" vol="+vol+" Raytemp="+Raytemp);

		mRayTemperatureValue = (short)Raytemp;
		mOldAdcValueRay = adcValue;
		
		return mRayTemperatureValue;
	}

测试:
光机内部温度(SAR3):

万用表测得S-5813A输出电压也是1.74V,而因光机是密封的、不能拆开,需要用I2C读取光机温度值,来判断误差多大。

光机外部温度(热敏电阻检测),即DMD温度(SAR1):

最后用温度测量仪矫对测试结果。

其他
上面是使用公式将ADC值转温度值,有另外一种方法是制作两个表值,表一是ADC值,表二是从通过I2C读取光机温度值,两个表可定制出光机温度曲线图,然后将两个表数据集成到代码。这种做法相对来说获取的温度值更加准确,缺点是代码移植性较差、在采集光机温度值时可能烧坏光机。

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章