单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 376|回复: 0
收起左侧

恒流PT100温度检测报警装置单片机程序与仿真 测温范围-99~400℃

[复制链接]
a1357787200 发表于 2019-6-12 18:56 | 显示全部楼层 |阅读模式
基于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. /*一、主要功能:
  2. (1)PT100数字温度计.
  3. (2)采集测温范围为-99 ℃~400 ℃.
  4. (3) 精度4度,误差+-2度.
  5. (4)显示模块,采用4个LED数码管显示.
  6. (5) 蜂鸣器报警温度大于50度报警。
  7. */
  8. #include<reg52.h>
  9. #include<intrins.h>
  10. #define uint unsigned int
  11. #define uchar unsigned char
  12. //-----------------------
  13. sbit SEG1=P2^0;                    //段码位1
  14. sbit SEG2=P2^2;                    //段码位2  
  15. sbit SEG3=P2^4;                    //段码位3
  16. sbit SEG4=P2^6;                    //段码位4

  17. sbit CS  = P1^0; //ADC0832片选
  18. sbit CLK = P1^1; //ADC0832时钟
  19. sbit DIO = P1^2; //输入输出

  20. sbit BUZ = P3^0; //蜂鸣器报警设置

  21. uchar dispaly[3];         //显示缓冲
  22. uchar tem[11]={10,10,20,13,11,11,15,21,18,29,11};
  23. uchar  ng;                                  //负号标志
  24. uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x58,0x00,0x40};//共阴数码码表01000000
  25.                  /* 0    1    2   3    4    5    6    7    8    9     C   无*/
  26. uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位
  27. //延时
  28. //************************************************************************/
  29. // 函数: LCD_Delay()
  30. // 描述: 延时t ms函数
  31. // 参数: t
  32. // 返回: 无
  33. // 备注: 12MHZ       t=1延时时间约1ms
  34. // 版本:  2011/01/01      First version
  35. //************************************************************************/
  36. void Delay_ms(unsigned int t)//延时1ms
  37. {
  38.         unsigned int i,j;
  39.         for(i=0;i<t;i++)
  40.         for(j=0;j<120;j++)
  41.         ;
  42. }
  43. /*******************
  44. 中值滤波函数
  45. *********************/
  46. uchar median(uchar *dat,uchar num_d)  //需要排序的数组
  47. { uchar i,j,temp;
  48. for (i=0;i<num_d;i++) //采用冒泡法对采样温度进行排序
  49.         for (j=0;j<num_d-i;j++)
  50.         {
  51.                 if (dat[i]>dat[i+1])
  52.                 {
  53.                         temp=dat[i];
  54.                         dat[i]=dat[i+1];
  55.                         dat[i+1]=temp;
  56.                 }
  57.         }
  58. return(dat[(num_d-1)/2]); //取中值并返回
  59. }
  60. /*******************电阻值计算函数*********************/
  61. float account_res(void)
  62. {        uchar temp;
  63.         float temp_r,d;

  64.         temp=median(tem,11); //利用中值法求取中间值
  65.         d = temp*500.0/256;//采集到的PT100上的压降
  66.         temp_r=d*3135/4096;//计算出电阻值 3300是R1
  67.         return(temp_r);
  68. }

  69. /*****************计算温度函数*******************/
  70. float temperature(void)
  71. { float temp1,T_out;
  72. uchar temp2;

  73. temp1=account_res(); //计算Pt100阻值
  74. temp2=(uint)temp1; //取Pt100阻值高位
  75. if(temp2<100){ng=1;}else{ng=0;}//负温度
  76. if(temp2<60) T_out=777;
  77.   else if(temp2<100) T_out=256.02-2.558*temp1; //若阻值在小于0℃到负99之间
  78.   else if(temp2<139) T_out=2.558*temp1-256.02; //若阻值在0~100℃之间
  79.   else if(temp2<177) T_out=2.637*temp1-267.01; //若阻值在100~200℃之间
  80.   else if(temp2<214) T_out=2.766*temp1-281.9; //若阻值在200~300℃之间
  81.   else if(temp2<250) T_out=2.865*temp1-300.94;  //若阻值在300~400℃之间
  82.   else if(temp2<260) T_out=2.81*temp1-300.94;  //若阻值在400℃之间
  83.   else if(temp2>260) T_out=777; //若阻值在大于400℃之间
  84.   return(T_out);
  85. }

  86. /*******************调整显示数据函数*******************/
  87. void adj_t(void)
  88. {
  89.         float temp_v;
  90.         uint value;          
  91.         temp_v=10*temperature(); //利用计算温度值
  92.         value=(uint)temp_v;
  93. if((value>500)&&(ng==0)){BUZ=0;}else{BUZ=1;}//蜂鸣器50度报警,开,关蜂鸣器

  94.         if(value==7770) //超出测量范围
  95.         {         Display_Digit[0]=12; //显示'E'
  96.                 Display_Digit[1]=12; //显示'E'
  97.                 Display_Digit[2]=12; //显示'E'
  98.                 Display_Digit[3]=12; //显示'E'
  99.         }
  100.         else {  Display_Digit[3]=value/1000; //待显示百位
  101.                     Display_Digit[2]=(value%1000)/100; //待显示十位
  102.                     Display_Digit[1]=((value%1000)%100)/10; //待显示个位
  103.                            Display_Digit[0]=(value%1000)%100%10; //待显示小数
  104.                 if(Display_Digit[3]==0x00) { Display_Digit[3]=11; if(Display_Digit[2]==0) Display_Digit[2]=11; }
  105.         }
  106. }

  107. void DIS_SEG(void)//在LED上显示数据
  108. {
  109.                         if(ng==1){P0=0x40;}else{P0=tab[Display_Digit[3]];}   // 数码管显示负数 或正的1000位
  110.                         SEG1=0;                    //片选1000位数码管      
  111.                         Delay_ms(2);    //延时3ms
  112.             SEG1=1;                         //关闭1000位数码管

  113.                         P0=tab[Display_Digit[2]]; //温度100位     
  114.                         SEG2=0;                        //片选100位数码管
  115.                         Delay_ms(2);    //延时3ms
  116.             SEG2=1;                 //关闭100位数码管

  117.                         P0=(tab[Display_Digit[1]]+0x80); //温度10位
  118.                         SEG3=0;                        //片选10位数码管
  119.                         Delay_ms(2);    //延时3ms
  120.             SEG3=1;                 //关闭10位数码管

  121.                     P0=tab[Display_Digit[0]];    //个数位
  122.                         SEG4=0;                        //片选个位数码管
  123.                         Delay_ms(2);    //延时3ms
  124.             SEG4=1;                 //关闭个位数码管
  125. }
  126. //------------------------------------------------------------------------
  127. //获取指定通道的A/D转换结果
  128. //------------------------------------------------------------------------
  129. uchar Get_AD_Result(void)
  130. {
  131.         uchar i,dat1=0,dat2=0;

  132.         CS  = 0; _nop_(); _nop_();                                                 //片选使能,低电平有效
  133.         CLK = 0; _nop_(); _nop_();                                                  //芯片时钟输入
  134.         DIO = 1; _nop_(); _nop_();
  135.         CLK = 1; _nop_(); _nop_();
  136.         //第1个下降沿之前,设DI=1/0
  137.         //选择单端/差分(SGL/DIF)模式中的单端输入模式       
  138.         CLK = 0;DIO = 1; _nop_(); _nop_();
  139.         CLK = 1;         _nop_(); _nop_();
  140.         //第2个下降沿之前,设置DI=0/1,选择CHO/CH1

  141.         CLK = 0;DIO = 0; _nop_(); _nop_(); //通道0 内部电压测试

  142.         CLK = 1;                 _nop_(); _nop_();
  143.         //第3个下降沿之前,设置DI=1
  144.         CLK = 0;DIO = 1; _nop_(); _nop_();
  145.    //第4-11个下降沿读数据(MSB->LSB)
  146.         for(i=0;i<8;i++)
  147.         {
  148.                  CLK = 1; _nop_(); _nop_();
  149.                 CLK = 0; _nop_(); _nop_();
  150.                 dat1 = dat1 << 1 | DIO;               
  151.         }
  152.         //第11-18个下降沿读数据(LSB->MSB)
  153.         for(i=0;i<8;i++)
  154.         {
  155.                 CLK = 1; _nop_(); _nop_();
  156.                 CLK = 0; _nop_(); _nop_();
  157.                  dat2 = dat2 << ((uchar)(DIO)<<i);
  158.         }
  159.         CS = 1;//取消片选一个周期结束
  160.         //如果MSB->LSB和LSB->MSB读取的结果相同,则返回读取的结果,否则返回0
  161.         return dat1;
  162. //        return (dat1 == dat2) ? dat1:0;//取消校验
  163. }

  164. void main(void)
  165. {   uchar j;
  166.         BUZ=1;//关蜂鸣器
  167.         while(1)
  168.         {
  169.         tem[0]=Get_AD_Result(); //读取温度值存入缓冲区
  170.         tem[1]=Get_AD_Result(); //读取温度值存入缓冲区
  171.         tem[2]=Get_AD_Result(); //读取温度值存入缓冲区
  172.         tem[3]=Get_AD_Result(); //读取温度值存入缓冲区
  173.         tem[4]=Get_AD_Result(); //读取温度值存入缓冲区
  174.         tem[5]=Get_AD_Result(); //读取温度值存入缓冲区
  175.         tem[6]=Get_AD_Result(); //读取温度值存入缓冲区
  176.         tem[7]=Get_AD_Result(); //读取温度值存入缓冲区
  177.         tem[8]=Get_AD_Result();        //读取温度值存入缓冲区
  178.         tem[9]=Get_AD_Result(); //读取温度值存入缓冲区
  179.         tem[10]=Get_AD_Result();//读取温度值存入缓冲区       
  180.         adj_t();// 调整显示数据函数//50度报警。
  181.         for(j=0;j<250;j++){DIS_SEG();}//显示数据
  182.    }
  183. }
复制代码
0.png
所有资料51hei提供下载:
51heiPT100.zip (125.77 KB, 下载次数: 19)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

快速回复 返回顶部 返回列表