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通道     
     
    }


}


////////////////////////////////////////////////////


///////////////////////////////////////////////////