NTC热敏电阻设计高精度温度计的方案1
2019-04-15 12:51 发布
生成海报
采用廉价的NTC热敏电阻设计高精度温度计的方案, 根据NTC热敏电阻的温度特性,采用了较具新意程序算法;摆脱了传统的查表显示温度的方法, 特点:程序中无须查表,打破了常规的查表显示温度的方法。
#include
#include
#include
#include
#include
#include
#include
#include "drive.h"
unsigned int code V0=2320;//2.32伏=>R=32660 2.5K Vref=2.5V
// unsigned int code V0=3828;//3.828伏=>R=32660 10K Vref=5V
//uchar code K=2;
uchar TUP0=1;//在0度上
uint idata Vtest=0;
unsigned int code NTC[71]={//-10度 ~ +60度
55350,52420,49670,47080,44640,42340,40170,38130,36200,34380,
32660,30140,29510,28060,26690,25400,24180,23020,21920,20890,
19900,18970,18090,17260,16470,15710,15000,14320,13680,13070,
12490,11940,11420,10920,10450,10000,9572,9165,8777,8408,
8055,7721,7402,7098,6808,6531,6267,6015,5774,5545,
5325,5116,4916,4725,4543,4368,4201,4041,3888,3742,
3602,3468,3340,3217,3099,2987,2878,2775,2675,2580,
2488
};
//-----------------PID--------
uint idata Tempurature;//测得实际温度
float idata Pset=0,Iset=0,Dset=0;//实际上每个扩大了
uchar code TRange=100;//控温范围0-10
float idata VRange;//输出范围0-2V
float idata Et_Cool=0,Et1_Cool=0,Et2_Cool=0;//制冷
float idata Tset;//设置温度
unsigned int Vout;
//unsigned char idata Data[2];
unsigned int code WriteNum[8]={2000,77,100,1500,1000,2050,250,0x88}; //p I D Tset A1 A2 MAXI
//unsigned int idata ReadNum[8];
float idata T_Alarm1,T_Alarm2;
float idata outValue_Cool=0.0;
uint PIDOut_Cool();
uint GetTemperature(uchar IsTest);//如果25.0度返回2500
uint ReadAD(uchar port);
void initPID();
void ReadDataToBuf();
//////////////////////
//////////////////////
sbit Alarm1=P0^0;
sbit Alarm2=P0^1;
sbit TECON =P2^6;
sbit CoolON=P2^1;
//-----------------------------
//////////////////////////////////////////////////////////
////// IsTest为1表示为测试温度,为0表示环境温度
///// 分压电阻为2500欧姆
// 2.39 =>-10 R=55350欧姆
// |
// 2.32 =>0 R=32660欧姆
// |
// 2 =>25 R=10000欧姆
// |
// 1.25 =>60 R=2488欧姆
///////////////////////////////////////////////////////////
uint GetTemperature( )//如果25.0度返回2500
{
float Temp;
unsigned char i;
bit find;
unsigned int Rtest,Ttest;
DOG=!DOG;
find=0;
i=0;
if (Vtest>V0) //零度以下 负温度系数
TUP0=0;
else
TUP0=1;
Rtest=2500*(Vtest/(2.5*1000-Vtest));//分压电阻为2.5K 总电压为2.5V
while(!find)
{
if (NTC[i]>=Rtest && NTC[i+1]<=Rtest)
find=1;
else
i++;
}
if (TUP0)
Temp=(float)(i-10)+(float)(NTC[i]-Rtest)/(NTC[i]-NTC[i+1]);
else
Temp=(float)(10-i)+(float)(NTC[i]-Rtest)/(NTC[i]-NTC[i+1]);
DOG=!DOG;
Ttest=fabs(Temp*100);
return Ttest;
}
///////////////////////////////////////////////////////////
uint ReadAD(uchar port)
{ uint ad2,AD; float a,Vin,all,MaxV,MinV; uchar i; DOG=!DOG; read2543(port); AD=0; ad2=read2543(port); //vref=5.00*(ad2/4096.00); i=0; all=0; a=0; MaxV=0; MinV=5;
for (i=0;i<255;i++)
{
DOG=!DOG;
ad2=read2543(port);
a=5.0*ad2/4096.00;
if (a > MaxV) MaxV=a;
if (a < MinV) MinV=a;
all+=a;
}
all=all-MaxV-MinV;
Vin=(all/253.0);
Vin*=1000;
AD=abs(Vin);
read2543(port);
return AD;
}
//////////////////////////////////////////////////////////
/////////////////// PID ///////////////////////////////
void initPID()
{
Et_Cool=0.0;
Et1_Cool=0.0;
Et2_Cool=0.0;
}
//******************************
//******************************
//------------制冷--------------
uint PIDOut_Cool()
{
float Pa=0,Pb=0,Pc=0;
float Pterm=0.0,Iterm=0.0,Dterm=0.0,Cool_Out;
DOG=!DOG;
if (TUP0)
Et_Cool=Tempurature-Tset*100;//Tset=25 ,扩大100倍
else
Et_Cool=((-1)*Tempurature)-Tset*100;//Tset=25 ,扩大100倍
Pa=Et_Cool;
Pb=Et_Cool-Et1_Cool;
Pc=Et_Cool-2*Et1_Cool+Et2_Cool;
Pterm=(float)Pset*Pb;
Iterm=(float)Iset*Pa;
Dterm=(float)Dset*Pc;
outValue_Cool+=Pterm+Iterm+Dterm;//P、I、D增量算法
Cool_Out=outValue_Cool;
//------------------
if (outValue_Cool > TRange*100)
outValue_Cool=TRange*100;//分辨率为Trange=100,100X100=10000
if (outValue_Cool<0) outValue_Cool=0;
if (Cool_Out > (TRange*100)) Cool_Out=TRange*100;//分辨率为Trange=100,100X100=10000
if (Cool_Out<0) Cool_Out=0;
if (!TUP0) Cool_Out=0;
//------------------
Et2_Cool=Et1_Cool;
Et1_Cool=Et_Cool;
return Cool_Out;//还原为0-100输出,然后扩大100倍100X100=10000
}
//***************************************
///////////////////////////////////////////////////////////
/*
void ReadDataToBuf()
{
uchar i;
for (i=0;i<7;i++)
{
DOG=!DOG;
RW24XX(Data,2,0x0000+i*2, 0xa1,M2464);
ReadNum[i]=Data[0]*256+Data[1];
}
}
*/
//****************************************
//********************* *****************
//********************* 主程序 *****************
//********************* ****************
void main(void)
{
uint Cur_Temp;
uint out=0;
//////////////////
uchar i;
DOG=0;
DOG=!DOG;
P0&=0;
Alarm1=1;
Alarm2=1;
TECON=0;
CoolON=1;
//////////////////
for (i=0;i<200;i++) ;
InitMax7219();
ClsMax7219();
DOG=!DOG;
InitMAX512();
initPID();
/*
//////////////////////////////////////////////
RW24XX(Data,2,0x0000+7*2, 0xa1,M2464);
ReadNum[7]=Data[0]*256+Data[1];
if (ReadNum[7]!=0x88)
{
for (i=0;i<7;i++)
{
DOG=!DOG;
Data[0]=WriteNum[i]/256;
Data[1]=WriteNum[i]%256;
RW24XX(Data,2,0x0000+i*2, 0xa0,M2464);
}
}
/////////////////////////////////////////
ReadDataToBuf();
*/
DOG=!DOG;
Pset= (float)WriteNum[0]/100.0;//读取参数
Iset= (float)WriteNum[1]/100.0;
Dset= (float)WriteNum[2]/100.0;
Tset= (float)WriteNum[3]/100.0;
T_Alarm1= (float)WriteNum[4]/100.0;
T_Alarm2= (float)WriteNum[5]/100.0;
VRange= (float)WriteNum[6]/100.0;
DOG=!DOG;
InitMAX512();
ClsMax7219();
//======设定温度 =========
MAX7219_ShowFloat(1,Tset*10,1);//如405为40.5
while (1)
{
DOG=!DOG;
Vtest=ReadAD(0);//pt100A
//================ 测试实际温度 ================
Tempurature=GetTemperature();//如25.0为2500 实际温度
///============== 制冷 =====================
if (Tempurature>=1500) CoolON=1;//制冷打开
else
CoolON=0; //制冷关闭
//-------------报警--------------------------
if (Tempurature
{
Delay(200);
if (Tempurature
Alarm1=0;
}
else
Alarm1=1;
if (Tempurature>T_Alarm2*100 && TUP0)
{
Delay(200);
if (Tempurature>T_Alarm2*100 && TUP0)
Alarm2=0;
}
else
Alarm2=1;
/////
Cur_Temp=(uint)Tempurature/10;
MAX7219_ShowFloat(2,Cur_Temp,TUP0);//如405为40.5
out=PIDOut_Cool();
if (out>0) TECON=1;
else TECON=0;
Vout=(uint)(10.0*VRange*((float)out/TRange)); //如2V为2000
DAOut(0x01,Vout/10.0);//如2V为200 A通道
}
}
////////////////////////////////////////////////////
///////////////////////////////////////////////////
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮