基于PT100的温度检测报警装置仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
运放电源电压必须得6V,否则输出电压不准。 AD转换ADC0832的电压需要为5V
数字式温度计 测温范围,-99~400℃
(-100度测试)RV1=60Ω 显示温度-99.2度 误差0.5度
(0度测试)RV1=100Ω 显示温度0.5度 ,误差0.5度
(100度测试)RV1=140Ω 显示温度103.5度,误差0.5度
(200度左右测试)RV1=180Ω 显示温度214.2度,误差约0.5度
(300度左右测试)RV1=210Ω 显示温度292.8度,误差约1度
(380度左右测试)RV1=240Ω 显示温度380度,误差约0.5度
单片机源程序如下:
- /*一、主要功能:
- (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[i]>dat[i+1])
- {
- temp=dat[i];
- dat[i]=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();}//显示数据
- }
- }
复制代码
所有资料51hei提供下载:
51heiPT100.zip
(125.77 KB, 下载次数: 235)
|