關于PT100的程序:http://www.zg4o1577.cn/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();}//顯示數據
}
}
|