找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1489|回复: 1
打印 上一主题 下一主题
收起左侧

单片机DS18B20智能温控系统程序与Proteus仿真图

[复制链接]
跳转到指定楼层
楼主
温度监控系统采用单片机进行控制,由温度检测电路、显示电路、A/D 转换电路、执行机构、控制电路和单片微处理器等组成。用单片机作为控制器,可对执行机构发出指令,实现温度参数调,温度实时显示等功能。系统下位机由传感器检测模块,键盘显示模块和执行机构模块三大部分构成。

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include<reg52.h>         //51单片机的头文件
  2. #include<intrins.h>   //函数程序中需要使用到空指令
  3. /***_crol_ 字符循环左移
  4.     _cror_ 字符循环右移
  5.     _irol_ 整数循环左移
  6.     _iror_ 整数循环右移
  7.     _lrol_ 长整数循环左移
  8.     _lror_ 长整数循环右移
  9.     _nop_ 空操作 (相当于8051 NOP 指令)
  10.     _testbit_ 测试并清零位 (相当于8051 JBC 指令) ***/
  11. #define dm P0          //段码输出口
  12. #define uchar unsigned char //宏定义,用uchar来代替unsigned char(无符号字符型变量,也即是无符号的8位变量),                                         
  13. //宏定义的原因就是书写方便,宏定义后,uchar可直接用来定义变量
  14. #define uint unsigned int  //原因同上,不过要注意,unsigned int为无符号的整型变量
  15. //sbit是用来管脚的。
  16. sbit DQ=P1^0;          //温度输入口
  17. sbit w0=P2^4;          //数码管4
  18. sbit w1=P2^5;          //数码管3
  19. sbit w2=P2^6;          //数码管2
  20. sbit w3=P2^7;          //数码管1
  21. sbit beep=P2^0;   //蜂鸣器
  22. sbit jidianqi=P2^1; //继电器
  23. sbit yellow=P3^5;          //加热指示灯
  24. sbit led=P3^6;            //高温指示灯
  25. sbit zc=P3^7;         //系统运行正常指示灯
  26. sbit set=P3^4;                     //选择设置
  27. sbit add=P3^3;                  //加
  28. sbit dec=P3^2;                  //减
  29. int temp1=0;//最高温度和最低温度标志位         
  30. uint h;
  31. uint temp;        //温度函数
  32. uchar r;
  33. uchar high=30,low=28;        //开机默认最高温度和最低温度
  34. uchar sign;
  35. uchar q=0;
  36. uchar tt=0;
  37. uchar scale;
  38. uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09};          //共阳小数断码表
  39. uchar code table_dm[12]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0xbf};          //共阳LED段码表"0""1""2""3""4""5""6""7""8""9""不亮""-"
  40. uchar code table_dm1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};        //共阳个位带小数点的断码表
  41. uchar data temp_data[2]={0xff,0xff};//读出温度暂放
  42. uchar data display[5]={0xff,0xff,0xff,0xff,0xff};//显示单元数据,共四个数据和一个运算暂用
  43. /***************11us延时函数***************/
  44. void delay(uint t)
  45. {
  46.         for(;t>0;t--);
  47. }
  48. /***************数码管显示***************/
  49. void scan()
  50. {
  51.         int j;
  52.         for(j=0;j<4;j++)
  53.         {
  54.                 switch(j)
  55.                 {
  56.                         case 0:
  57.                         dm=table_dm[display[0]];;
  58.                         w0=0;  //打开数码管显示小数数字的数码管位选端
  59.                         delay(50);
  60.                         w0=1;        //关闭数码管显示小数数字的数码管位选端
  61.                         case 1:
  62.                         dm=table_dm1[display[1]];
  63.                         w1=0;  //打开数码管显示个位数字的数码管位选端
  64.                         delay(50);
  65.                         w1=1;        //关闭数码管显示个位数字的数码管位选端
  66.                         case 2:
  67.                         dm=table_dm[display[2]];
  68.                         w2=0;        //打开数码管显示十位数字的数码管位选端
  69.                         delay(50);
  70.                         w2=1;        //关闭数码管显示十位数字的数码管位选端
  71.                         case 3:
  72.                         dm=table_dm[display[3]];
  73.                         w3=0;        //打开数码管显示百位数字的数码管位选端
  74.                         delay(50);
  75.                         w3=1;        //关闭数码管显示百位数字的数码管位选端
  76.                 }
  77.         }
  78. }
  79. /****温度传感器采用的是DS18b20,此传感器采用的
  80. 是“单总线”来传输数据。****/
  81. /**************DS18B20初始化**************/
  82. ow_reset(void)         //初始化
  83. {
  84.         char presence=1;
  85.         while(presence)
  86.         {
  87.                 while(presence)
  88.                 {
  89.                         DQ=1;_nop_();_nop_();   //将数据线拉高并延时
  90.                         DQ=0;           //将DQ(P1.0)引脚拉低。请注意,这里的DQ不是变量,而是单片机的引脚!!!                 
  91.                         delay(50);   //延时
  92.                         DQ=1;     //将DS拉高
  93.                         delay(6);
  94.                         presence=DQ;
  95.                 }
  96.                 delay(45);
  97.                 presence=~DQ;
  98.         }
  99.         DQ=1;        
  100.         return presence;
  101. }
  102. /****************写命令函数*****************/
  103. void write_byte(uchar val)
  104. {
  105.         uchar i;
  106.         for(i=8;i>0;i--)
  107.         {
  108.                 DQ=1;_nop_();_nop_();    //将数据线拉高并延时
  109.                 DQ=0;_nop_();_nop_();_nop_();_nop_();          //将数据线拉低并延时
  110.                 DQ=val&0x01;
  111.                 delay(6);
  112.                 val=val>>1;               
  113.         }
  114.         DQ=1;
  115.         delay(1);
  116. }        
  117. /****************读一个字节函数*******************/
  118. uchar read_byte(void)
  119. {
  120.         uchar i;
  121.         uchar value=0;
  122.         for(i=8;i>0;i--)  //采用for 循环,读取原始温度数据
  123.         {
  124.                 DQ=1;_nop_();_nop_();
  125.                 value>>=1;
  126.                 DQ=0;_nop_();_nop_();_nop_();_nop_();
  127.                 DQ=1;_nop_();_nop_();_nop_();_nop_();
  128.                 if(DQ)value|=0x80;
  129.                 delay(6);
  130.         }
  131.         DQ=1;        
  132.         return value;
  133. }
  134. /***************读取温度函数***************/
  135. read_temp()           //读取18b20传感器函数
  136. {
  137.         ow_reset();
  138.         delay(200);
  139.         write_byte(0xcc);
  140.         write_byte(0x44);
  141.         ow_reset();
  142.         delay(1);
  143.         write_byte(0xcc);
  144.         write_byte(0xbe);
  145.         temp_data[0]=read_byte();
  146.         temp_data[1]=read_byte();
  147.         temp=temp_data[1];
  148.         temp<<=8;
  149.         temp=temp|temp_data[0];
  150.         return temp;
  151. }
  152. /***************温度数据处理函数***************/
  153. work_temp(uint tem)         //温度转换函数
  154. {
  155.         uchar n=0;
  156.         if(tem>6348)
  157.         {
  158.                 tem=65536-tem;
  159.                 n=1;
  160.         }
  161.         display[4]=tem&0x0f;
  162.         display[0]=ditab[display[4]];
  163.         display[4]=tem>>4;
  164.         display[3]=display[4]/100;
  165.         display[1]=display[4]%100;
  166.         display[2]=display[1]/10;
  167.         display[1]=display[1]%10;
  168.         r=display[1]+display[2]*10+display[3]*100;
  169.         if(!display[3])
  170.         {
  171.                 display[3]=0x0a;
  172.                 if(!display[2])        
  173.                 {
  174.                         display[2]=0x0a;
  175.                 }
  176.         }
  177.         if(n)
  178.         {
  179.                 display[3]=0x0b;
  180.         }
  181.         return n;
  182. }
  183. /***************报警提示电路***************/
  184. void BEEP()
  185. {
  186.    
  187.         {zc=0;}         //系统正常指示灯
  188.         if(r>=high&&r<129)         //如果实际温度高于等于于设定温度
  189.         {
  190.                 led=0;//保温灯亮
  191.                 beep=0;//蜂鸣器响
  192.                 jidianqi=1; //继电器停止加热
  193.                 yellow=1;//加热灯灭
  194.         }
  195.         else  //否则
  196.         {
  197.                 beep=1;//蜂鸣器停
  198.         }
  199.         if(r<low)         //如果实际温度小于设定温度
  200.         {
  201.                 yellow=0;//加热灯亮
  202.             led=1;//保温灯灭
  203.                 jidianqi=0;          //继电器开始加热
  204.         }
  205. }
  206. /***************温度显示转换**************/
  207. void xianshi(int horl)                 //数码管显示函数
  208. {
  209.         int n=0;
  210.         if(horl>128)
  211.         {
  212.                 horl=256-horl;
  213.                 n=1;
  214.         }
  215.         display[3]=horl/100;         //         显示千位
  216.         display[3]=display[3]&0x0f;          //显示千位
  217.         display[2]=horl%100/10;                   // 显示百位
  218.         display[1]=horl%10;                                // 显示个位
  219.         display[0]=0;                          // 显示分
  220.         if(!display[3])
  221.         {
  222.                 display[3]=0x0a;
  223.                 if(!display[2])        
  224.                 {
  225.                         display[2]=0x0a;
  226.                 }
  227.         }
  228.         if(n)
  229.         {
  230.                 display[3]=0x0b;
  231.         }                                                                                
  232. }
  233. /**************按键设置*************/
  234. void keyscan()
  235. {
  236.         int temp1;    //最高温度和最低温度标志位
  237.         if(set==0)          //设置按键按下按键低电平有效
  238.         {
  239.                 while(1)
  240.                 {
  241.                         delay(500);//消抖
  242.                         if(set==0)         //只有按下松手后,再按按键才能再次使设定值自加一次
  243.                         {
  244.                                 temp1++;  //设定值自加一次
  245.                                 while(!set)
  246.                                 scan();
  247.                         }
  248.                         if(temp1==1)
  249.                         {
  250.                                 xianshi(high);
  251.                                 scan();
  252.                                 if(add==0)
  253.                                 {
  254.                                         while(!add)
  255.                                         scan();
  256.                                         high+=1;
  257.                                 }
  258.                                 if(dec==0)
  259.                                 {
  260.                                         while(!dec)
  261.                                         scan();
  262.                                         high-=1;
  263.                                 }
  264.                         }
  265.                         if(temp1==2)
  266.                         {
  267.                                 xianshi(low);
  268.                                 if(add==0)
  269.                                 {
  270.                                         while(!add)
  271.                                         scan();
  272.                                         low+=1;
  273.                                 }
  274.                                 if(dec==0)
  275.                                 {
  276.                                         while(!dec)
  277.                                         scan();
  278.                                         low-=1;
  279.                                 }
  280.                                 scan();
  281.                         }
  282.                         if(temp1>=3)
  283.                         {
  284.                                 temp1=0;
  285.                                 break;
  286.                         }
  287.                 }
  288.         }
  289. }
  290. /**************主函数*************/
  291. void main()
  292. {
  293.         dm=0x00; //对P0口初始化,开机让数码管显示(000.0)
  294.         w0=0;         //关闭数码管位选W0~W3
  295.         w1=0;
  296.         w2=0;
  297.         w3=0;
  298.         for(h=0;h<4;h++)
  299.         {
  300.                 display[h]=0;
  301.         }
  302.         ow_reset();
  303.         write_byte(0xcc);
  304.         write_byte(0x44);
  305.         for(h=0;h<100;h++)
  306.         {
  307.                 scan();
  308.         }
  309.         while(1)                  //循环
  310.         {
  311.                 if(temp1==0)
  312.                 {
  313.                         work_temp(read_temp());
  314.                         scan();
  315.                         BEEP();
  316.                         keyscan();
  317.                 }
  318.                 else        
  319.                         keyscan();
  320.             
  321.         }        
  322. }
  323. /*****************结束*****************//*****************结束*****************/
复制代码

Keil代码与Proteus8.13仿真下载:
温控.7z (1.58 MB, 下载次数: 39)

评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:492633 发表于 2023-3-13 21:19 来自手机 | 只看该作者
这不是我的图吗?虽然程序也是转别人的魔改的
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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