自从想要做一个PT100的测温电路,实验了很多方法,包括恒流源,电桥。最后决定使用恒流源,而恒流源采用压控恒流源,电压基准采用LM285,输出电压1.235V。

此恒流源的输出电流取决于LM285的输出电压,和R1的阻值,为了得到精确的输出电流,R1最好采用高精度,低温漂的电阻。如果需要更高的精度,则需要使用更高的电压基准芯片,比如REF5025,LM399等。

PT100采用四线制接法,通过J2输入,放大器采用AD623仪表放大器,当然使用普通运放构成差分放大器也是可以的,只是使用现成的仪表放大器比较方便,只需要一个外部电阻R15即可设置放大增益,公式为G=100KΩ/R15+1,这个电路设置的放大增益G=11。另外U8、C7、C8、R17、R18构成二阶有源低通滤波器,这里设置的截止频率f≈5Hz。滤波后的信号接ADC到单片机的模数转换引脚,当然也可以通过跳线JP1接到专用16位AD转换芯片ADS1110,将电压转换为数字信号然后交由单片机处理。

本电路因为采用单电源供电,而AD623需要使用一个负电压,所以使用了一个电压反转芯片MAX660,但也可以使用LM2662替代,而事实上在实际的电路中,我使用的就是LM2662

这是单片机电路的原理图,使用的是 STC的STC12C5A16S2,LQFP44封装。其中KEY,DATA,CLK,CS是用来控制数码管,用于显示测量温度,在这个环节中,使用了一片HD7279芯片,用于动态显示数码管,为什么使用这个芯片而不是使用单片机直接驱动数码管呢。这个是出于节省CPU资源的考虑,因为程序中使用了一些滤波算法比较耗费CPU,而且考虑到可能需要使用485通信,万一等待时间过长,担心因此造成数码管闪烁,所以使用了一片HD7279。

这个是核心板输出接口电路

关于这个芯片的使用方法就不多说了,datasheet上写的非常清楚了。

当然,显示部分的电路是和核心电路分开的,在另外一块PCB上。下面是核心板的PCB

以下是标定数据,“温度计”项代表使用标准水银温度计的测量值;“PT100“代表以上装置测量得出的值;”误差“为”PT100“-”温度计“的值;”多项式“是采用多项式拟合后的到的值;”拟合后误差”为”多项式“-”温度计“的值;

 温度计 PT100 误差               多项式         拟合后误差
2 6 -4 2.3 0.3
2.7 6.7 -4 3.1 0.4
3 7 -4 3.5 0.5
4 8 -4 4.7 0.7
7 10 -3 7.2 0.2
8.9 11.1 -2.2 8.5 -0.4
9 12 -3 9.6 0.6
9.2 11.3 -2.1 8.8 -0.4
9.2 12.4 -3.2 10.1 0.9
9.5 11.4 -1.9 8.9 -0.6
10 11.7 -1.7 9.3 -0.7
10 12.8 -2.8 10.6 0.6
10.2 12.2 -2 9.9 -0.3
11.2 12.8 -1.6 10.6 -0.6
11.5 14.2 -2.7 12.3 0.8
12 13 -1 10.8 -1.2
12 14 -2 12.0 0.0
12.2 13.9 -1.7 11.9 -0.3
13 15 -2 13.2 0.2
13.5 15.2 -1.7 13.5 0.0
14 16 -2 14.4 0.4
14 15.6 -1.6 14.0 0.0
14.2 15.1 -0.9 13.4 -0.8
22.5 22.3 0.2 21.9 -0.6
23 22.7 0.3 22.3 -0.7
23.5 22.9 0.6 22.6 -0.9
24 23.3 0.7 23.0 -1.0
24.5 24.9 -0.4 24.9 0.4
24.5 23.8 0.7 23.6 -0.9
25 25.2 -0.2 25.2 0.2
25 24.3 0.7 24.2 -0.8
25.5 25.7 -0.2 25.8 0.3
26 26.2 -0.2 26.4 0.4
26.5 26.6 -0.1 26.9 0.4
27 27.1 -0.1 27.4 0.4
27.5 27.4 0.1 27.8 0.3
28 27.8 0.2 28.2 0.2
28.5 28.2 0.3 28.7 0.2
29 28.7 0.3 29.3 0.3
29.5 29 0.5 29.6 0.1
30 29.5 0.5 30.2 0.2
30.7 30 0.7 30.7 0.0
31 30.3 0.7 31.1 0.1
31.5 30.7 0.8 31.5 0.0
32 31 1 31.9 -0.1
32 31.2 0.8 32.1 0.1
32.5 32.6 -0.1 33.7 1.2
32.5 31.6 0.9 32.5 0.0
33 32.1 0.9 33.1 0.1
34 33 1 34.1 0.1
34.5 33.4 1.1 34.5 0.0
38 36.2 1.8 37.7 -0.3
39 37 2 38.5 -0.5
40 38 2 39.6 -0.4
41 39 2 40.7 -0.3
42 40.5 1.5 42.4 0.4
44 41.7 2.3 43.6 -0.4
45 42.6 2.4 44.6 -0.4
46 43.5 2.5 45.6 -0.4
47 44.6 2.4 46.8 -0.2
48 45.6 2.4 47.8 -0.2
49 46.5 2.5 48.8 -0.2
50 47.6 2.4 49.9 -0.1
51 48.5 2.5 50.9 -0.1
54 51.5 2.5 54.0 0.0
55 52.5 2.5 55.0 0.0
56 53.5 2.5 56.0 0.0
58 55.5 2.5 58.1 0.1
59.2 56.5 2.7 59.1 -0.1
60 57.5 2.5 60.1 0.1
61 58.3 2.7 60.9 -0.1
62 59.4 2.6 62.0 0.0
63 60.5 2.5 63.1 0.1
64 61.5 2.5 64.1 0.1
65.2 62.5 2.7 65.1 -0.1
66 63.5 2.5 66.0 0.0
67.2 64.5 2.7 67.0 -0.2
68 65.5 2.5 68.0 0.0
70 67.6 2.4 70.0 0.0
71 68.2 2.8 70.6 -0.4
72 69.4 2.6 71.7 -0.3
73 70.5 2.5 72.8 -0.2
74 71.5 2.5 73.7 -0.3
75 72 3 74.2 -0.8
76 74 2 76.0 0.0
77.5 74.9 2.6 76.9 -0.6
78 76 2 77.9

-0.1

上图中X轴为PT100的值,Y轴为温度计的值,可以看出多项式拟合的效果更好一些

以下是实物效果:

下面是程序代码:

#include <intrins.h>
#include <STC12C5A60S2.H>typedef unsigned int  uint;
typedef unsigned char uchar;
typedef unsigned short WORD;float code RTD_TAB_PT100[151] =   // 表格是以1度为一步,即-20, -19, -18.....
{ 88.22, 88.62 ,88.62, 89.40, 89.80, 90.19, 90.59, 90.98, 91.37, 91.77,       //  -30 ~ -2192.16, 92.55, 92.95, 93.34, 93.73, 94.12, 94.52, 94.91, 95.30, 95.69,       //  -20 ~ -1196.09, 96.48, 96.87, 97.26, 97.65, 98.04, 98.44, 98.83, 99.22, 99.61,       //  -10 ~ -1 100.00,100.39,100.78,101.17,101.56,101.95,102.34,102.73,103.13,103.51,       //   0  ~ 9103.90,104.29,104.68,105.07,105.46,105.85,106.24,106.63,107.02,107.49,       //  10  ~ 19107.79,108.18,108.57,108.96,109.35,109.73,110.12,110.51,110.90,111.28,       //  20  ~ 29111.67,112.06,112.45,112.83,113.22,113.61,113.99,114.38,114.77,115.15,       //  30  ~ 39115.54,115.93,116.31,116.70,117.08,117.47,117.86,118.24,118.62,119.01,       //  40  ~ 49119.40,119.78,120.16,120.55,120.93,121.32,121.70,122.09,122.47,122.86,       //  50  ~ 59123.24,123.62,124.01,124.39,124.77,125.16,125.54,125.92,126.31,126.69,       //  60  ~ 69127.07,127.45,127.84,128.22,128.60,128.98,129.37,129.75,130.13,130.51,       //  70  ~ 79130.89,131.27,131.66,132.04,132.42,132.80,133.18,133.56,133.94,134.32,       //  80  ~ 89134.70,135.08,135.46,135.84,136.22,136.60,136.98,137.36,137.74,138.12,       //  90  ~ 99138.50,138.88,139.26,139.64,140.02,140.39,140.77,141.15,141.53,141.91,       // 100  ~ 109142.29,142.66,143.04,143.42,143.80,144.17,144.55,144.93,145.31,145.68,       // 110  ~ 119146.06                                                              // 120
}; sbit beep = P3^5;//----------------ADS1110地址、配置字-----------------//
#define      ADS1110_WR_ADDRESS   0x92        // 1001 001 0 写
#define      ADS1110_RD_ADDRESS   0x93        // 1001 001 1 读
#define      ADS1110_CONFIG_REG   0x8C        // 连续转换模式,16bit精度,PGA=1     sbit  ADS1110_SDA = P1^5;    // 模拟I2C数据传输位
sbit  ADS1110_CLK = P1^6;    // 模拟I2C时钟控制位//uchar TMR_H, TMR_L;             // AD转换高8位,和低8位
uint  AD_Result[25];
unsigned long nTmp;//*** HD7279 函数定义 ***
void long_delay(void);                          // 长延时
void short_delay(void);                         // 短暂延时
void delay10ms(unsigned char);                  // 延时10MS
void write7279(uchar, uchar);   // 写入到HD7279
uchar read7279(uchar);          // 从HD7279读出
void send_byte(uchar);                  // 发送一个字节
uchar receive_byte(void);               // 接收一个字节sbit cs =P0^7;                    // cs at P1.4
sbit clk=P0^6;                 // clk 连接于 P1.5
sbit dat=P0^5;                 // dat 连接于 P1.2
sbit key=P0^4;                 // key 连接于 P1.3
sbit Hight_LED = P4^6;
sbit Low_LED   = P4^1;//****** HD7279A 指令 ******
#define CMD_RESET 0xa4
#define CMD_TEST  0xbf
#define DECODE0   0x80
#define DECODE1   0xc8
#define CMD_READ  0x15
#define UNDECODE  0x90
#define RTL_CYCLE 0xa3
#define RTR_CYCLE 0xa2
#define RTL_UNCYL 0xa1
#define RTR_UNCYL 0xa0
#define ACTCTL    0x98
#define SEGON     0xe0
#define SEGOFF    0xc0
#define BLINKCTL  0x88//-------- AT24C04 变量声明 ---------
sbit _24C02_SCL = P2^6;                //AT24C04的时钟
sbit _24C02_SDA = P2^5;                //AT24C04的数据uchar BUF[16];                   //数据缓存区uint code nDefaultDATA[] =
{// nLowTMP   nHightTMP  nTMPAdj480,       650,       0      // 默认设置
};
uint nSettingDATA[3] = {0, 0, 0};  // 当前设置void Delay5us();
void AT24C04_Start();
void AT24C04_Stop();
void AT24C04_SendACK(bit ack);
bit AT24C04_RecvACK();
void AT24C04_SendByte(uchar dat);
uchar AT24C04_RecvByte();
void AT24C04_ReadPage();
void AT24C04_WritePage();//****** 红外接收 ******
sbit IRIN = P3^3;         //红外接收器数据线
uchar IRCOM[7];
uchar nFlag = 0;
uchar nMode = 1;   // nMode    0       1          2         3   // mean   NULL nLowTMP   nHightTMP   nTMPAdjuint nLowTMP   = 480;   // 最低温度设定
uint nHightTMP = 650;    // 最高温度设定
char nTMPAdj   = 0;          // 温度修正void send_ad_result(uchar temp);/***********************************************************************************
************************************************************************************
HD 7279 函数
************************************************************************************
************************************************************************************/
void write7279(uchar cmd, uchar dta)
{cs = 0;send_byte (cmd);send_byte (dta);cs = 1;
}   uchar read7279(uchar command)
{cs = 0;send_byte(command);return(receive_byte());cs = 1;
}void send_byte(    uchar out_byte)
{uchar i;cs=0;long_delay();for (i=0;i<8;i++){if (out_byte&0x80){ dat=1;}else{dat=0;}clk=1;short_delay();clk=0;short_delay();out_byte=out_byte*2;}dat=0;
}uchar receive_byte(void)
{uchar i, in_byte;dat=1;               // set to input modelong_delay();for (i=0;i<8;i++){clk=1;short_delay();in_byte=in_byte*2;if (dat){in_byte=in_byte|0x01;}clk=0;short_delay();}dat=0;return (in_byte);
}void delay10ms(uint time)   //误差 -0.000000000001us
{uchar a,b,c;uint i;for (i=0;i<time;i++){for(c=7;c>0;c--)for(b=168;b>0;b--)for(a=24;a>0;a--);}
}void long_delay(void)
{unsigned char i;for (i=0;i<0x30;i++);
}void short_delay(void)
{unsigned char i;for (i=0;i<8;i++);
}/***********************************************************************************
************************************************************************************
HD 7279 函数 END
************************************************************************************
************************************************************************************///--------------------- 模块延时程序_1ms -------------------------
void delay1ms(uint delay1ms) //STC11F60XE,延时1ms
{uchar a,b;// 12M
//    for(;delay1ms>0;delay1ms--)
//        for(b=222;b>0;b--)
//            for(a=12;a>0;a--);// 11.0592Mfor( ; delay1ms > 0; delay1ms--)for(b = 21; b > 0; b--)for(a = 130; a > 0; a--);
}void Delay5us()   // 晶振11.0592M 误差 -0.026765046296us
{uchar a;for(a=12;a>0;a--);_nop_();
}void delay(uint delay) //STC11F60XE,12M,延时170us
{   uchar a,b;// 12M
//  for(;delay>0;delay--)
//      for(b=78;b>0;b--)
//          for(a=5;a>0;a--);// 11.0592Mfor( ; delay > 0; delay--)for( b = 2; b > 0; b--)for( a = 232; a > 0; a--);
}//--------------------- 数码管显示函数 -------------------------
void Display_TMP(uint nTmp1)
{//send_byte(CMD_RESET);write7279(DECODE0,nTmp1/100%100);delay1ms(2);write7279(DECODE0+1,nTmp1/10%10);delay1ms(2);write7279(SEGON,15);delay1ms(2);write7279(DECODE0+2,nTmp1%10);delay1ms(2);write7279(SEGON,63);delay1ms(2);write7279(SEGON,62);delay1ms(2);write7279(SEGON,61);delay1ms(2);write7279(SEGON,60);delay1ms(2);write7279(SEGON,59);delay1ms(2);//delay10ms(1000); //send_byte(CMD_RESET);
}void Display_SETTMP(uint nTmp2)
{//send_byte(CMD_RESET);write7279(DECODE0+4,nTmp2/100%100);delay1ms(2);write7279(DECODE0+5,nTmp2/10%10);delay1ms(2);write7279(SEGON,47);delay1ms(2);write7279(DECODE0+6,nTmp2%10);delay1ms(2);write7279(SEGON,31);delay1ms(2);write7279(SEGON,30);delay1ms(2);write7279(SEGON,29);delay1ms(2);write7279(SEGON,28);delay1ms(2);write7279(SEGON,27);delay1ms(2);//delay10ms(1000); //send_byte(CMD_RESET);
}void Display_SET()
{send_byte(CMD_RESET);if (nMode == 1)  // set nLowTMP{write7279(SEGON,1);delay1ms(2);write7279(SEGON,2);delay1ms(2);write7279(SEGON,3);delay1ms(2);write7279(DECODE0+4,nLowTMP/100%100);delay1ms(2);write7279(DECODE0+5,nLowTMP/10%10);delay1ms(2);write7279(SEGON,47);delay1ms(2);write7279(DECODE0+6,nLowTMP%10);}if (nMode == 2)   // set nHightTMP{write7279(SEGON,0);delay1ms(2);write7279(SEGON,1);delay1ms(2);write7279(SEGON,2);delay1ms(2);write7279(SEGON,4);delay1ms(2);write7279(SEGON,5);delay1ms(2);write7279(DECODE0+4,nHightTMP/100%100);delay1ms(2);write7279(DECODE0+5,nHightTMP/10%10);delay1ms(2);write7279(SEGON,47);delay1ms(2);write7279(DECODE0+6,nHightTMP%10);}if (nMode == 2)     // set nTMPAdj{write7279(SEGON,0);delay1ms(2);write7279(SEGON,1);delay1ms(2);write7279(SEGON,2);delay1ms(2);write7279(SEGON,4);delay1ms(2);write7279(SEGON,5);delay1ms(2);write7279(SEGON,6);delay1ms(2);if (nTMPAdj < 0){write7279(SEGON,32);delay1ms(2);write7279(DECODE0+5,(0-nTMPAdj)/10%10);delay1ms(2);write7279(DECODE0+6,(0-nTMPAdj)%10);}if (nTMPAdj > 0){write7279(DECODE0+5,nTMPAdj/10%10);delay1ms(2);write7279(DECODE0+6,nTMPAdj%10);}}
}
/***********************************************************************************
************************************************************************************
红外解码 函数-BEGIN/
************************************************************************************
************************************************************************************/
void IR_IN() interrupt 2 using 0
{return ;
}
/***********************************************************************************
红外解码 函数 END
************************************************************************************//***********************************************************************************
************************************************************************************
AD1110 转换 -BEGIN/
************************************************************************************
************************************************************************************//*******************************************************************************
名称:ads1110Start(void)
功能:ADS1110 I2C Start
********************************************************************************/
void ads1110Start(void)
{    ADS1110_SDA = 1;_nop_(); _nop_(); _nop_();_nop_(); _nop_(); ADS1110_CLK = 1; _nop_(); _nop_();   _nop_();  _nop_(); _nop_();  _nop_();ADS1110_SDA = 0; _nop_();  _nop_();  _nop_();  _nop_(); _nop_();  _nop_();
} /*******************************************************************************
名称:ads1110Stop(void)
功能:ADS1110 I2C Stop
********************************************************************************/
void ads1110Stop(void)
{    ADS1110_SDA = 0;_nop_();  _nop_();_nop_();  _nop_();_nop_();  _nop_(); ADS1110_CLK = 1;                // -----------结束I2C总线._nop_();  _nop_();  _nop_();  _nop_(); _nop_();  _nop_();_nop_();  _nop_();   ADS1110_SDA = 1;_nop_(); _nop_(); _nop_();
}
/*******************************************************************************
名称:waitAck(void)
功能:ADS1110 I2C 等待ack
********************************************************************************/
uchar waitAck(void)
{      uint i = 0;ADS1110_CLK = 1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); while((ADS1110_SDA==1)&&(i<500))i++;ADS1110_CLK = 0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_();return 0x00;
}/*******************************************************************************
名称:void sendAck(void)
功能:向ADS1110 I2C 发送 ack
********************************************************************************/
void sendAck(void)
{        ADS1110_SDA=0; _nop_();   _nop_();    _nop_();   _nop_();   ADS1110_CLK=1;_nop_();   _nop_();    _nop_();   _nop_();  ADS1110_CLK=0;
}
/*******************************************************************************
名称:void sendNotAck(void)
功能:向ADS1110 I2C 不发送 ack
********************************************************************************/
void sendNotAck(void)
{     ADS1110_SDA=1; _nop_();   _nop_();    _nop_();   _nop_();ADS1110_CLK=1;_nop_();   _nop_();    _nop_();   _nop_();  ADS1110_CLK=0;
} /*******************************************************************************
名称:void ads1110SendByte(uchar sendData)
功能:向ADS1110 I2C 发送1个字节
********************************************************************************/
void ads1110SendByte(uchar sendData)
{    uchar i,temp;temp = sendData;for(i=0;i<8;i++){temp = temp << 1;ADS1110_CLK = 0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_();  _nop_(); ADS1110_SDA = CY;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();ADS1110_CLK = 1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();}ADS1110_CLK = 0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();ADS1110_SDA = 1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();
} /*******************************************************************************
名称:uchar ads1110ReceiveByte(void)
功能:ADS1110 I2C 接收1个字节
********************************************************************************/
uchar ads1110ReceiveByte(void)
{          uchar i,k;ADS1110_CLK = 0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_();_nop_();  _nop_();ADS1110_SDA = 1;_nop_();  _nop_();_nop_();  _nop_();_nop_();  _nop_();for(i=0;i<8;i++){ADS1110_CLK = 1;_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();k= (k << 1)| ADS1110_SDA;ADS1110_CLK = 0;_nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();  _nop_();        }_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();  _nop_();return k;}  /*******************************************************************************
名称:ads1110Config(void)
功能:对ADS1110进行配置
********************************************************************************/
void ads1110Config(void)
{    ads1110Start();    ads1110SendByte(ADS1110_WR_ADDRESS);    waitAck();    ads1110SendByte(ADS1110_CONFIG_REG);    waitAck();    ads1110Stop();
}
/*******************************************************************************
名称:读取ADS1100数据子程序
功能:
********************************************************************************/
uint RD_ADS()
{uchar temp;uint  W_B1byte_high, W_B1byte_low, W_B1_word;   ads1110Start();                                 ads1110SendByte(ADS1110_RD_ADDRESS);    temp = waitAck();                            if(!temp)                              {   W_B1byte_high /*= TMR_H*/ = ads1110ReceiveByte();      sendAck();                W_B1byte_low /*= TMR_L*/ = ads1110ReceiveByte();         sendAck();                   temp = ads1110ReceiveByte();            ads1110Stop();   W_B1_word = (W_B1byte_high << 8)+ W_B1byte_low;   if (W_B1_word > 0x7fff)               W_B1_word = 0;   return W_B1_word;       }    else      return 0x0000;
}/*******************************************************************************
名称: 取AD结果函数
功能: 它是16位AD转换,连续去制25次,去掉3最大值和3个最小值,剩下19个取平均值
返回: 平均取值
********************************************************************************/
uint get_ad_result()
{ uchar i,j;uint temp;nTmp = 0;for(i = 0; i < 25; i++)    // 连续取值25次{AD_Result[i] = RD_ADS();delay1ms(10);}for(i = 1;  i< 25; i++)     // 插入法对取的25个值进行排序{temp = AD_Result[i];                          //store the original sorted array in tempfor(j=i ; j>0 && temp < AD_Result[j-1] ; j--) //compare the new array with temp   {AD_Result[j] = AD_Result[j-1];              //all larger elements are moved one pot to the right   }AD_Result[j] = temp;}//  for(i = 3; i < 22; i++)    // 去掉3最大值和3个最小值,余下19个值求和
//  {
//      nTmp = nTmp + AD_Result[i];
//  }return AD_Result[12]; //nTmp / 19;      // 取剩下19个数平均值//ad_average_result=ad_average_result*4*5000/1024;
}/*******************************************************************************
名称: 串口发送函数
功能: 取AD结果函数发送到串口,方便调试
返回: 无
********************************************************************************/
void send_ad_result(uchar temp)
{               SBUF = temp;while(TI == 0) ;TI = 0;delay1ms(100);//SBUF=R>>4;
}/*******************************************************************************
名称: 初始化函数
功能: 设置串口相关寄存器值,波特率取9600, 12T模式
返回: 无
********************************************************************************/
void _initiate() //初始化函数
{ EA = 1;ES = 0;TMOD = 0x20;  // 定时计数器方式控制寄存器,"自动重装,16位计数器".SCON = 0x50;  // 串行控制寄存器,方便在串口助手那观察// 12M
//  TH1 = 0xF3;      // 定时器初值高8位设置
//  TL1 = 0xF3;      // 定时器初值低8位设置// 11.0592M     波特率 9600TH1 = 0xFD;   // 定时器初值高8位设置TL1 = TH1;    // 定时器初值低8位设置PCON = 0x00;TR1 = 1;// IE = 0x84;      // 允许总中断中断,使能 INT1 外部中断EX1 = 1;
//  TCON = 0x10;    // 触发方式为脉冲负边沿触发
}/*******************************************************************************
名称: 蜂鸣器函数
功能: 设置蜂鸣器鸣响
返回: 无
********************************************************************************/
void Beep(uchar nSet)
{
}/****************************************/
/****************************************/
//------------ AT24C04 驱动函数  --------------/**************************************
向AT24C04写1页(16字节)数据
将TESTDATA开始的16个测试数据写如设备的00~0F地址中
**************************************/
void AT24C04_WritePage()
{uchar i;AT24C04_Start();            //起始信号AT24C04_SendByte(0xa0);     //发送设备地址+写信号AT24C04_SendByte(0x00);     //发送存储单元地址for (i=0; i<3; i++){AT24C04_SendByte(nSettingDATA[i]);}AT24C04_Stop();             //停止信号
}/**************************************
从AT24C04读取1页(16字节)数据
将设备的00~0F地址中的数据读出存放在DATA区的BUF中
**************************************/
void AT24C04_ReadPage()
{uchar i;AT24C04_Start();            //起始信号AT24C04_SendByte(0xa0);     //发送设备地址+写信号AT24C04_SendByte(0x00);     //发送存储单元地址AT24C04_Start();            //起始信号AT24C04_SendByte(0xa1);     //发送设备地址+读信号for (i=0; i<16; i++){BUF[i] = AT24C04_RecvByte();if (i == 15){AT24C04_SendACK(1); //最后一个数据需要会NAK}else{AT24C04_SendACK(0); //回应ACK}}AT24C04_Stop();             //停止信号
}/**************************************
起始信号
**************************************/
void AT24C04_Start()
{_24C02_SDA = 1;                    //拉高数据线_24C02_SCL = 1;                    //拉高时钟线Delay5us();                 //延时_24C02_SDA = 0;                    //产生下降沿Delay5us();                 //延时_24C02_SCL = 0;                    //拉低时钟线
}/**************************************
停止信号
**************************************/
void AT24C04_Stop()
{_24C02_SDA = 0;                    //拉低数据线_24C02_SCL = 1;                    //拉高时钟线Delay5us();                 //延时_24C02_SDA = 1;                    //产生上升沿Delay5us();                 //延时
}/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void AT24C04_SendACK(bit ack)
{_24C02_SDA = ack;                  //写应答信号_24C02_SCL = 1;                    //拉高时钟线Delay5us();                 //延时_24C02_SCL = 0;                    //拉低时钟线Delay5us();                 //延时
}/**************************************
接收应答信号
**************************************/
bit AT24C04_RecvACK()
{_24C02_SCL = 1;                    //拉高时钟线Delay5us();                 //延时CY = _24C02_SDA;                   //读应答信号_24C02_SCL = 0;                    //拉低时钟线Delay5us();                 //延时return CY;
}/**************************************
向IIC总线发送一个字节数据
**************************************/
void AT24C04_SendByte(uchar dat)
{uchar i;for (i=0; i<8; i++)         //8位计数器{dat <<= 1;              //移出数据的最高位_24C02_SDA = CY;               //送数据口_24C02_SCL = 1;                //拉高时钟线Delay5us();             //延时_24C02_SCL = 0;                //拉低时钟线Delay5us();             //延时}AT24C04_RecvACK();
}/**************************************
从IIC总线接收一个字节数据
**************************************/
uchar AT24C04_RecvByte()
{uchar i;uchar dat = 0;_24C02_SDA = 1;                    //使能内部上拉,准备读取数据for (i=0; i<8; i++)         //8位计数器{dat <<= 1;_24C02_SCL = 1;                //拉高时钟线Delay5us();             //延时dat |= _24C02_SDA;             //读数据_24C02_SCL = 0;                //拉低时钟线Delay5us();             //延时}return dat;
}/***********************************************************************
*FunName: float CalculateTemperature(float fR)
*
*In: fR -> PT100的电阻值。
*
*Out: fTem -> 测得的温度值。
*
*Discription: 将电阻值查表算出温度值。
*
*Notes:  采用2分查找法。
*
************************************************************************/
float CalculateTemperature(float fR)
{ float fTem; float fLowRValue; float fHighRValue; int   iTem; uchar i; uchar cBottom, cTop; if (fR < RTD_TAB_PT100[0]) // 电阻值小于表格最小值,低于量程下限。 { return 210; } if (fR > RTD_TAB_PT100[150]) // 电阻值大于表格最大值,超出量程上限。 { return 211; } cBottom = 0;  cTop    = 150; for (i=75; (cTop-cBottom)!=1; ) // 2分法查表。 { if (fR < RTD_TAB_PT100[i]) { cTop = i; i = (cTop + cBottom) / 2; } else if (fR > RTD_TAB_PT100[i]) { cBottom = i; i = (cTop + cBottom) / 2; } else { iTem = (uint)i - 30;  fTem = (float)iTem; return fTem; } } iTem = (uint)i - 30;send_ad_result(0x00);fLowRValue  = RTD_TAB_PT100[cBottom]; fHighRValue = RTD_TAB_PT100[cTop];send_ad_result(cBottom);send_ad_result(cTop); fTem = ( (fR - fLowRValue) / (fHighRValue - fLowRValue) ) + iTem; // 表格是以5度为一步的。 // 两点内插进行运算。 return fTem;
} /*******************************************************************************
名称: main
功能: 主函数
返回: 无
********************************************************************************/
void main()
{  uint result,tmr,nResult_TMP;uchar TMR_H, TMR_L, nTemp_1,nTemp_2,nTemp_3;float fTMP;nTemp_1 = 2;nTemp_2 = 3;nTemp_3 = 0;// 设置看门狗 EN_WDT = 1,CLR_WDT = 1,IDLE_WDT = 1, PS2 = 1,PS1 = 1,PS0 = 1WDT_CONTR = 0x3f;IRIN=1;_initiate();      // 初始化      ads1110Config();  // 配置ADS1110,采用连续转换模式,16bit精度,PGA=1// 则采样电压值为 V = (OutCode * 2.048) / 32768P1M0 |= 0x00;     // 设P1_7为高阻模式 如: P1_0= #00000000BP1M1 |= 0x80;//AT24C04_ReadPage();delay(10);for (tmr=0; tmr<0x2000; tmr++);  // 上电延时send_byte(CMD_RESET);            // 复位HD7279Adelay1ms(5);Display_TMP(230);     // 设定初始值23.0℃delay1ms(5);Display_SETTMP(550);  // 设定初始值55.0℃while(1){result = get_ad_result();      // ADC取样,25次,中值滤波法TMR_H = (result >> 8) & 0xff;  // 取高八位TMR_L = result & 0xff;        // 取低八位//send_ad_result(TMR_H);//send_ad_result(TMR_L);//lTmp = resultfTMP = ((result*2.048)/32768 + 0.0029) / 11 / 0.001021;   // 用ADC转换的电压值计算电阻//send_ad_result(0x00);delay1ms(10);fTMP = CalculateTemperature(fTMP);   // 查表法转换温度值// 根据实际标定结果进行数据拟合,得到公式-----实际温度 = -0.0023*测量温度*测量温度 + 1.2692*测量温度 - 5.2778nResult_TMP = (uint)(10*(-0.0023*fTMP*fTMP + 1.2692*fTMP - 5.2778)) + nTMPAdj;    if (nTemp_1 != (nResult_TMP/100%100)){write7279(DECODE0,nResult_TMP/100%100);nTemp_1 = nResult_TMP/100%100;}if (nTemp_2 != (nResult_TMP/10%10)){write7279(DECODE0+1,(nResult_TMP/10%10)|0x80);nTemp_2 = nResult_TMP/10%10;}if (nTemp_3 != (nResult_TMP%100)){write7279(DECODE0+2,nResult_TMP%10);nTemp_3 = nResult_TMP%10;}TMR_H = (nResult_TMP >> 8) & 0xff;  // 取高八位TMR_L = nResult_TMP & 0xff;           // 取低八位send_ad_result(TMR_H);send_ad_result(TMR_L);WDT_CONTR = 0x3f;     // 喂狗 间隔9.1022s}
}

运行视频可以到以下地址观看:

https://v.youku.com/v_show/id_XMTc0OTg0NjUyOA==.html?spm=a2hzp.8244740.0.0

PT100恒流源测温电路【一】相关推荐

  1. 硬件手册——PT100精密测温电路

    PT100精密测温电路 一.需求分析 根据题目要求为:测温范围为0-100℃.测温精度要求为±1℃.由于铂电阻具有精度高.性能可靠.稳定性好的特点,且铂电阻的电阻相对变化率与温度的关系曲线线性度最好, ...

  2. PT100高精度测温电路 AD623+REF3030(转)

    源: PT100高精度测温电路 AD623+REF3030(很稳定)

  3. PT100高精度测温电路 AD623+REF3030(转载)

    PT100是一种正温度系数的热敏电阻.说到什么是正温度系数?就必须要结合负温度系数来讲了.随着温度的升高,电阻的阻值变大,就是正温度系数的热敏电阻,相反,如果随着温度的升高,电阻的阻值变小,就是负温度 ...

  4. PT100高精度测温电路 AD623+REF3030(很稳定)

    出处:https://blog.csdn.net/gflytu/article/details/53902929 PT100是一种正温度系数的热敏电阻.说到什么是正温度系数?就必须要结合负温度系数来讲 ...

  5. 热电阻PT100测温电路

    目录: 一.概述 二.桥式测温电路 三.恒流源式测温电路 四.PT100温度传感器分度表 ------------------------------------------------------- ...

  6. 基于铂电阻测温电路的设计

    基于铂电阻测温电路的设计## 标题 一.概述 铂电阻温度传感器是利用其电阻和温度成一定函数关系而制成的温度传感器,由于其测量准确度高.测量范围大.复现性和稳定性好等,被广泛用于中温(-200℃-650 ...

  7. 简易测温电路课程设计报告

    "模电"课程设计任务书 简易测温电路 2018 年 01 月 15日 目录 1. 设计任务描述  ------------------- - 1 - 1.1 设计任务 ------ ...

  8. 基于单片机的PT100热电偶测温仿真设计(#0002)

    功能描述 采用51单片机作为主控单元芯片: 采用PT100热电偶检测温度,测量范围:-50℃~200℃: 采用LM324作为信号放大电路: 采用ADC0804芯片对温度信号进行AD模数转换处理: 采用 ...

  9. 热电偶测温电路Multisim仿真及故障字典建立

    一.热电偶测温原理 1.简介 热电偶(thermocouple)是温度测量中常用的测温元件,它直接测量温度,并把温度信号转换成热电动势信号,通过电气仪表(二次仪表)转换成被测介质的温度. 2.热电势形 ...

  10. 《温度控制器PT100的测温查表分度表(1分度表)》 ---------lwl

    //pt100的数据表,从-49摄氏度到299摄氏度的PT100的电阻值,放大了100倍 const  uint16_t pt100_table[350] ={   8070,      8110,  ...

最新文章

  1. OpenGL 有时候纹理映射的部分问题
  2. 喜欢 Netflix 么?你应该感谢 FreeBSD
  3. mysql 中遍历查询_mysql中循环查询
  4. 8086处理器的无条件转移指令——《x86汇编语言:从实模式到保护模式》读书笔记13
  5. 进入“0”和“1”的世界
  6. 黄文俊:Serverless小程序后端技术分享
  7. 第十节:实现vue组件之间的通信
  8. 什么是数据脱敏(Data Masking)?
  9. 【C语言】break,continue的区别
  10. BroadcastReceiver入门
  11. java qq机器人_简单几步教你如何用Java快速制作一个QQ机器人
  12. keyshot渲染很慢_提高Keyshot逼真渲染的小技巧!
  13. 使用 Autel MaxiFlash Elite 进行 GM J2534 编程
  14. Hive文件存储格式(建表stored as 的五种类型)
  15. 浦江县教育计算机网上网认证系统,校园网使用FAQ
  16. 计算机网络有哪些分类方式,计算机网络有哪些分类?
  17. GB2312与utf16、utf8的汉字对照表
  18. 一家AI创业公司不平凡的2018年
  19. 2015春季实习生招聘 多益网络科技有限公司笔试+面试 游戏开发工程师
  20. Android SDK包功能介绍,中文开发API

热门文章

  1. windows s2019安装crucible-4.8.2
  2. 商业研究(13):下厨房,从投资角度看这个项目的前景和价值
  3. java将小写金额转为大写金额
  4. 无限战争选择服务器,无限战争新手攻略 新手入门必看技巧
  5. CentOS7快速配置服务器网卡聚合双bond方法
  6. 30天搞定Java--day6
  7. 第 7 章 —— 代理模式
  8. window无法访问此文件夹,请确保输入的文件名是正确的,并且您有权访问此文件夹
  9. [BZOJ2177][最小/最大(曼哈顿距离)生成树]曼哈顿最小生成树
  10. php情书之笛卡尔的情书,笛卡尔情书的秘密——心形函数的作图