关于PT100的程序:http://www.51hei.com/bbs/dpj-162811-1.html
解释一下代码的83到88,里边的数值是什么意义?如何得到的?
else if(temp2<100) T_out=256.02-2.558*temp1; //若阻值在小于0℃到负99之间
else if(temp2<139) T_out=2.558*temp1-256.02; //若阻值在0~100℃之间
else if(temp2<177) T_out=2.637*temp1-267.01; //若阻值在100~200℃之间
else if(temp2<214) T_out=2.766*temp1-281.9; //若阻值在200~300℃之间
else if(temp2<250) T_out=2.865*temp1-300.94; //若阻值在300~400℃之间
else if(temp2<260) T_out=2.81*temp1-300.94; //若阻值在400℃之间
下边是完整源程序
/*一、主要功能:
(1)PT100数字温度计.
(2)采集测温范围为-99 ℃~400 ℃.
(3) 精度4度,误差+-2度.
(4)显示模块,采用4个LED数码管显示.
(5) 蜂鸣器报警温度大于50度报警。
*/
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
//-----------------------
sbit SEG1=P2^0; //段码位1
sbit SEG2=P2^2; //段码位2
sbit SEG3=P2^4; //段码位3
sbit SEG4=P2^6; //段码位4
sbit CS = P1^0; //ADC0832片选
sbit CLK = P1^1; //ADC0832时钟
sbit DIO = P1^2; //输入输出
sbit BUZ = P3^0; //蜂鸣器报警设置
uchar dispaly[3]; //显示缓冲
uchar tem[11]={10,10,20,13,11,11,15,21,18,29,11};
uchar ng; //负号标志
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x58,0x00,0x40};//共阴数码码表01000000
/* 0 1 2 3 4 5 6 7 8 9 C 无*/
uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位
//延时
//************************************************************************/
// 函数: LCD_Delay()
// 描述: 延时t ms函数
// 参数: t
// 返回: 无
// 备注: 12MHZ t=1延时时间约1ms
// 版本: 2011/01/01 First version
//************************************************************************/
void Delay_ms(unsigned int t)//延时1ms
{
unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<120;j++)
;
}
/*******************
中值滤波函数
*********************/
uchar median(uchar *dat,uchar num_d) //需要排序的数组
{ uchar i,j,temp;
for (i=0;i<num_d;i++) //采用冒泡法对采样温度进行排序
for (j=0;j<num_d-i;j++)
{
if (dat>dat[i+1])
{
temp=dat;
dat=dat[i+1];
dat[i+1]=temp;
}
}
return(dat[(num_d-1)/2]); //取中值并返回
}
/*******************电阻值计算函数*********************/
float account_res(void)
{ uchar temp;
float temp_r,d;
temp=median(tem,11); //利用中值法求取中间值
d = temp*500.0/256;//采集到的PT100上的压降
temp_r=d*3135/4096;//计算出电阻值 3300是R1
return(temp_r);
}
/*****************计算温度函数*******************/
float temperature(void)
{ float temp1,T_out;
uchar temp2;
temp1=account_res(); //计算Pt100阻值
temp2=(uint)temp1; //取Pt100阻值高位
if(temp2<100){ng=1;}else{ng=0;}//负温度
if(temp2<60) T_out=777;
else if(temp2<100) T_out=256.02-2.558*temp1; //若阻值在小于0℃到负99之间
else if(temp2<139) T_out=2.558*temp1-256.02; //若阻值在0~100℃之间
else if(temp2<177) T_out=2.637*temp1-267.01; //若阻值在100~200℃之间
else if(temp2<214) T_out=2.766*temp1-281.9; //若阻值在200~300℃之间
else if(temp2<250) T_out=2.865*temp1-300.94; //若阻值在300~400℃之间
else if(temp2<260) T_out=2.81*temp1-300.94; //若阻值在400℃之间
else if(temp2>260) T_out=777; //若阻值在大于400℃之间
return(T_out);
}
/*******************调整显示数据函数*******************/
void adj_t(void)
{
float temp_v;
uint value;
temp_v=10*temperature(); //利用计算温度值
value=(uint)temp_v;
if((value>500)&&(ng==0)){BUZ=0;}else{BUZ=1;}//蜂鸣器50度报警,开,关蜂鸣器
if(value==7770) //超出测量范围
{ Display_Digit[0]=12; //显示'E'
Display_Digit[1]=12; //显示'E'
Display_Digit[2]=12; //显示'E'
Display_Digit[3]=12; //显示'E'
}
else { Display_Digit[3]=value/1000; //待显示百位
Display_Digit[2]=(value%1000)/100; //待显示十位
Display_Digit[1]=((value%1000)%100)/10; //待显示个位
Display_Digit[0]=(value%1000)%100%10; //待显示小数
if(Display_Digit[3]==0x00) { Display_Digit[3]=11; if(Display_Digit[2]==0) Display_Digit[2]=11; }
}
}
void DIS_SEG(void)//在LED上显示数据
{
if(ng==1){P0=0x40;}else{P0=tab[Display_Digit[3]];} // 数码管显示负数 或正的1000位
SEG1=0; //片选1000位数码管
Delay_ms(2); //延时3ms
SEG1=1; //关闭1000位数码管
P0=tab[Display_Digit[2]]; //温度100位
SEG2=0; //片选100位数码管
Delay_ms(2); //延时3ms
SEG2=1; //关闭100位数码管
P0=(tab[Display_Digit[1]]+0x80); //温度10位
SEG3=0; //片选10位数码管
Delay_ms(2); //延时3ms
SEG3=1; //关闭10位数码管
P0=tab[Display_Digit[0]]; //个数位
SEG4=0; //片选个位数码管
Delay_ms(2); //延时3ms
SEG4=1; //关闭个位数码管
}
//------------------------------------------------------------------------
//获取指定通道的A/D转换结果
//------------------------------------------------------------------------
uchar Get_AD_Result(void)
{
uchar i,dat1=0,dat2=0;
CS = 0; _nop_(); _nop_(); //片选使能,低电平有效
CLK = 0; _nop_(); _nop_(); //芯片时钟输入
DIO = 1; _nop_(); _nop_();
CLK = 1; _nop_(); _nop_();
//第1个下降沿之前,设DI=1/0
//选择单端/差分(SGL/DIF)模式中的单端输入模式
CLK = 0;DIO = 1; _nop_(); _nop_();
CLK = 1; _nop_(); _nop_();
//第2个下降沿之前,设置DI=0/1,选择CHO/CH1
CLK = 0;DIO = 0; _nop_(); _nop_(); //通道0 内部电压测试
CLK = 1; _nop_(); _nop_();
//第3个下降沿之前,设置DI=1
CLK = 0;DIO = 1; _nop_(); _nop_();
//第4-11个下降沿读数据(MSB->LSB)
for(i=0;i<8;i++)
{
CLK = 1; _nop_(); _nop_();
CLK = 0; _nop_(); _nop_();
dat1 = dat1 << 1 | DIO;
}
//第11-18个下降沿读数据(LSB->MSB)
for(i=0;i<8;i++)
{
CLK = 1; _nop_(); _nop_();
CLK = 0; _nop_(); _nop_();
dat2 = dat2 << ((uchar)(DIO)<<i);
}
CS = 1;//取消片选一个周期结束
//如果MSB->LSB和LSB->MSB读取的结果相同,则返回读取的结果,否则返回0
return dat1;
// return (dat1 == dat2) ? dat1:0;//取消校验
}
void main(void)
{ uchar j;
BUZ=1;//关蜂鸣器
while(1)
{
tem[0]=Get_AD_Result(); //读取温度值存入缓冲区
tem[1]=Get_AD_Result(); //读取温度值存入缓冲区
tem[2]=Get_AD_Result(); //读取温度值存入缓冲区
tem[3]=Get_AD_Result(); //读取温度值存入缓冲区
tem[4]=Get_AD_Result(); //读取温度值存入缓冲区
tem[5]=Get_AD_Result(); //读取温度值存入缓冲区
tem[6]=Get_AD_Result(); //读取温度值存入缓冲区
tem[7]=Get_AD_Result(); //读取温度值存入缓冲区
tem[8]=Get_AD_Result(); //读取温度值存入缓冲区
tem[9]=Get_AD_Result(); //读取温度值存入缓冲区
tem[10]=Get_AD_Result();//读取温度值存入缓冲区
adj_t();// 调整显示数据函数//50度报警。
for(j=0;j<250;j++){DIS_SEG();}//显示数据
}
}
|