找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 18440|回复: 43
收起左侧

单片机DS18B20温度检测及报警系统设计全套资料(仿真+代码+PCB)

  [复制链接]
ID:114903 发表于 2018-11-17 10:47 | 显示全部楼层 |阅读模式
(1)打印电路板将绘制好的电路板用转印纸打印出来,注意滑的一面面向自己,一般打印两张电路板,即一张纸上打印两张电路板。在其中选择打印效果最好的制作线路板。
(2)裁剪覆铜板用感光板制作电路板全程图解 。覆铜板,也就是两面都覆有铜膜的线路板,将覆铜板裁成电路板的大小,不要过大,以节约材料。
0.png

制作出来的实物图如下:

实物

实物


电路原理图如下:

总图

总图


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

仿真

仿真


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

pcb

pcb


/*元器件列表
材料 数量
LCD1602 1
蜂鸣器 1
USB母座 1
89c52 1
9脚103排阻 1
电阻10K 1
电阻1k 1
电阻4.7K 2
电位器10k 1
电解电容10uf 1
电容30pf 2
11.0592晶振 1
三极管pnp8550 1
四脚按键 5
排针 8
排针母座20p 1
稳定传感器18B20 1
插座40脚 1
覆铜板15X20 1
三脚开关 1
*/

电偶

电偶

码表

码表

控制

 控制

报警

报警

51系统

51系统

1602

1602

1602实物

1602实物


单片机源程序如下:
  1. #include <REGX52.H>
  2. sbit keyu=P3^4;//加按键
  3. sbit keyl=P3^5;//减按键
  4. sbit keyh=P3^6;//调节尺度
  5. sbit keym=P3^7; //转换模式
  6. sbit RS=P2^5;//数据/命令选择端(H/L)
  7. sbit RW=P2^6;//读/写端(H/L)
  8. sbit EN=P2^7;//使能
  9. sbit DQ=P2^0;  //DS18B20接入口
  10. sbit buzz=P2^1;//蜂鸣器接口        -
  11. bit f=1;  //正负温度标志位
  12. unsigned char  m=1,y=0,o=0;//寄存器
  13. unsigned int sdata;//存放整数温度
  14. unsigned char xiaoshu1;        //存放小数后第一位温度数值
  15. unsigned char xiaoshu2;         //存放小数后第二位温度数值
  16. unsigned char code huany[]=" Welcome to use "; //欢迎使用
  17. unsigned char code tt[]  =" ter thermometer"; //温度计
  18. unsigned char code duqu[]="   loading...   "; //读取
  19. unsigned char code tab1[]=" T:      C   M  ";        //框架
  20. unsigned char code tab2[]="U:        L:    ";
  21. unsigned char code shuzu[]="0123456789+- .*";        //数字,,10加号,,,11减号,,,12空格,,,,13点,,,,14*
  22. unsigned char u=40;//上限
  23. char l=15,p;
  24.                           //下限
  25. void delay_50us(unsigned int t)         //延时函数
  26. {
  27. unsigned int j,k;
  28. for (;t>0;t--)
  29. {
  30.   for(j=10;j>0;j--)
  31.   {
  32.    for(k=1;k>0;k--);
  33.   }
  34. }
  35. }
  36. void button() //报警蜂鸣器
  37. {
  38.   unsigned char k=2;
  39.   while(k--)
  40. {
  41.   buzz=0;delay_50us(200);
  42.   buzz=1;delay_50us(200);
  43. }
  44. }
  45. ///lcd
  46. void write_com(unsigned com)//写操纵
  47. {
  48.    EN=0;
  49.    RS=0;
  50.    RW=0;
  51.    P0=com;
  52.    delay_50us(1);
  53.    EN=1;
  54.    delay_50us(5);
  55.    EN=0;
  56. }
  57. void write_data(unsigned char dat)//写数据
  58. {
  59.    EN=0;
  60.    RS=1;
  61.    RW=0;
  62.    P0=dat;
  63.    delay_50us(1);
  64.    EN=1;
  65.    delay_50us(5);
  66.    EN=0;
  67. }
  68. void init(void)//初始化
  69. {
  70.      delay_50us(5);
  71.          write_com(0x38);
  72.          delay_50us(1);
  73.          write_com(0x38);
  74.          delay_50us(1);
  75.          write_com(0x38);
  76.          write_com(0x38);
  77.          write_com(0x08); //只开显示
  78.          write_com(0x01); //清屏
  79.          write_com(0x06);//地址加1,当写入数据的时候光标右移
  80.          write_com(0x0C); //开显示,不显示光标
  81. }  
  82. void delay_18B20(unsigned int i)        //18b20全局延时
  83. {
  84.   while(i--);
  85. }
  86. ///////////////////////////////////18b20//////////////////////////////////////////////////
  87. //初始化传感器函数
  88.   Init_DS18B20(void)
  89.   {
  90.   unsigned char x=0;
  91.   DQ=1;//DQ复位
  92.   delay_18B20(10);//稍做延时
  93.   DQ=0;//单片机将DQ拉低
  94.   delay_18B20(80);//精确延时大于480us
  95.   DQ=1;//拉高总线
  96.   delay_18B20(20);
  97.   x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败
  98.   delay_18B20(30);
  99.   return x;
  100. }
  101. //读一个字节
  102. ReadOneChar(void)
  103. {
  104.    unsigned char i=0;
  105.    unsigned char dat=0;
  106.    for(i=8;i>0;i--)
  107.    {
  108.       DQ=0;//给脉冲信号
  109.       dat>>=1;
  110.       DQ=1;//给脉冲信号
  111.       if(DQ)
  112.       dat|=0x80;
  113.       delay_18B20(4);
  114.    }
  115.    return(dat);
  116. }
  117. //写一个字节
  118. WriteOneChar(unsigned char dat)
  119. {
  120.    unsigned char i=0;
  121.    for(i=8;i>0;i--)
  122.    {
  123.       DQ=0;
  124.       DQ=dat&0x01;
  125.       delay_18B20(5);
  126.       DQ=1;
  127.       dat>>=1;
  128.    }
  129.    return(dat);
  130. }
  131. void ReadTemperature(void)
  132. {
  133.    unsigned char L=0;
  134.    unsigned char H=0;
  135.    Init_DS18B20();
  136.    WriteOneChar(0xCC);//跳过读序号列号的操作
  137.    WriteOneChar(0x44);//启动温度转换
  138.    delay_18B20(100);
  139.    Init_DS18B20();
  140.    WriteOneChar(0xCC);//跳过读序号列号的操作
  141.    WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器前两个就是 温度               
  142.    L=ReadOneChar();
  143.    H=ReadOneChar();
  144.    if(H>0xf8)              //高位前五位为1时温度是负
  145.    {
  146.                 L=~L+1;
  147.                 H=~H;   
  148.                 f=0;                                              //读取温度为负时fg=0
  149.                 sdata = L/16+H*16;              //整数部分
  150.             xiaoshu1 = (L&0x0f)*10/16;                 //小数第一位
  151.             xiaoshu2 = (L&0x0f)*100/16%10;        //小数第二位
  152.         }
  153. //传感器返回值除16得实际温度值
  154. //为了得到2位小数位,先乘100,再除16,考虑整型数据长度,
  155.         else
  156.            {
  157.             f=1;
  158.         sdata = L/16+H*16;                   //整数部分
  159.             xiaoshu1 = (L&0x0f)*10/16;                 //小数第一位
  160.             xiaoshu2 = (L&0x0f)*100/16%10;        //小数第二位
  161.         }
  162. }
  163. ///////////////////18b20结束/////////////
  164. void display0()//显示welcome   to use the  
  165. {
  166.        unsigned char i,w,h=0x8f,i1,w1,h1=0xcf,w2,i2,h2,g=2;
  167.        init();
  168.            for(w=0;w<16;w++)  //显示欢迎
  169.            {
  170.                write_com(h--);//第一行自减左移
  171.                for(i=0;i<16;i++)
  172.                {
  173.                   write_data(huany[i]);
  174.                           delay_50us(15);
  175.                }
  176.            }
  177.            for(w1=0;w1<16;w1++)//第二行自减左移
  178.            {
  179.                write_com(h1--);
  180.                for(i1=0;i1<16;i1++)
  181.                {
  182.                   write_data(tt[i1]);
  183.                           delay_50us(15);
  184.                }
  185.            }
  186.        delay_50us(5000);//显示loading
  187.            init();
  188.            write_com(0x80);
  189.            for(w2=0;w2<16;w2++)//向右显示
  190.            {            
  191.            write_data(duqu[w2]);
  192.                    delay_50us(200);               
  193.            }
  194.            while(g--)//小数点循环亮灭
  195.            {   
  196.                write_com(0x8a);
  197.                for(i2=0;i2<3;i2++)
  198.                {
  199.                       write_data(duqu[i2]);
  200.                            
  201.                    }
  202.                    write_com(0x8a);
  203.                for(h2=10;h2<14;h2++)
  204.                    {  
  205.                       delay_50us(300);
  206.                       write_data(duqu[h2]);
  207.                           delay_50us(300);
  208.                    }
  209.            }
  210.       
  211. }
  212. void display1()        //显示框架
  213. {
  214.        unsigned char p,q;
  215.        init();//全局清零
  216.        write_com(0x80);
  217.        for(q=0;q<16;q++)//显示TMHL
  218.        {
  219.           write_data(tab1[q]);
  220.        }  
  221.        write_com(0xc1);
  222.        for(p=0;p<16;p++)  
  223.        write_data(tab2[p]);
  224. }
  225. void display2()//显示上下限温度        ,尺度
  226. {
  227.    //尺度

  228.       write_com(0x8e);
  229.       write_data(shuzu[m/10]);//十位
  230.       write_com(0x8f);
  231.       write_data(shuzu[m%10]);//个位
  232.    if(o==1)                   //上限选中标志*号可操作
  233.    {
  234.      write_com(0xc0);
  235.      write_data(shuzu[14]);
  236.      write_com(0xca);
  237.      write_data(shuzu[12]);
  238.    }
  239.    else if(o==2)        //下限选中标志*号可操作
  240.    {
  241.       write_com(0xca);
  242.       write_data(shuzu[14]);
  243.       write_com(0xc0);
  244.       write_data(shuzu[12]);
  245.    }
  246.    else if(o==0)         //隐藏*号不可操作
  247.    {
  248.       write_com(0xca);
  249.       write_data(shuzu[12]);
  250.       write_com(0xc0);
  251.       write_data(shuzu[12]);
  252.    }
  253.    if(u/100==0)         //上限100内温度
  254.    {
  255.       write_com(0xc3);
  256.       write_data(shuzu[12]);//空格
  257.       write_com(0xc4);
  258.       write_data(shuzu[u/10]);//十位
  259.       write_com(0xc5);
  260.       write_data(shuzu[u%10]);//个位
  261.    }
  262.    else if (u/100==1)//上限100外温度
  263.    {
  264.       write_com(0xc3);
  265.       write_data(shuzu[u/100]);//百位
  266.       write_com(0xc4);
  267.       write_data(shuzu[(u-100)/10]);//十位
  268.       write_com(0xc5);
  269.       write_data(shuzu[u%10]);//个位
  270.    }
  271. //下限温度
  272.    if (l<0)//下限低于0的温度显示
  273.    {
  274.       p=-l;
  275.       write_com(0xcD);
  276.       write_data(shuzu[11]);//负号
  277.       write_com(0xcE);
  278.       write_data(shuzu[p/10]);
  279.       write_com(0xcF);
  280.       write_data(shuzu[p%10]);
  281.    }
  282.    else if(l>=0)//下限高于0的温度显示
  283.    {  
  284.       write_com(0xcD);
  285.       write_data(shuzu[12]);         
  286.       write_com(0xcE);
  287.       write_data(shuzu[l/10]);
  288.       write_com(0xcF);
  289.       write_data(shuzu[l%10]);
  290.    }
  291. }  
  292. void fuhao()        //温度正负子程序
  293. {
  294.             if(f==1) //温度为正
  295.          {
  296.             write_com(0x83);
  297.         write_data(shuzu[12]);
  298.          }
  299.          else if(f==0) //温度为负,显示负号
  300.          {
  301.             write_com(0x83);
  302.         write_data(shuzu[11]);
  303.          }
  304. }
  305. void display(unsigned int date)         //显示温度,
  306. {
  307.       if(date/100==0) //100度内
  308.       {
  309.          write_com(0x84);
  310.          write_data(shuzu[date/10]);//十位
  311.          write_com(0x85);
  312.          write_data(shuzu[date%10]);//个位
  313.          write_com(0x86);
  314.          write_data(shuzu[13]);//小数点
  315.          write_com(0x87);
  316.          write_data(shuzu[xiaoshu1]);//小数点后一位
  317.          write_com(0x88);
  318.          write_data(shuzu[xiaoshu2]); //小数点后二位
  319.       }
  320.       else if(date/100==1)          //100度上
  321.       {
  322.          write_com(0x83);
  323.          write_data(shuzu[date/100]);//百位
  324.          write_com(0x84);
  325.          write_data(shuzu[(date-100)/10]);//十位
  326.          write_com(0x85);
  327.          write_data(shuzu[date%10]);//个位
  328.          write_com(0x86);
  329.          write_data(shuzu[13]);//点
  330.          write_com(0x87);
  331.          write_data(shuzu[xiaoshu1]);//小数点后一位
  332.          write_com(0x88);
  333.          write_data(shuzu[xiaoshu2]);//小数点后二位
  334.       }
  335. }

  336. void key()                //按键加减标尺

  337. {
  338. //尺度
  339.    if(keym==0)//判定
  340.    {
  341.      delay_50us(100);//延时
  342.      if(keym==0)
  343.      {        
  344.        y++;//转换加减的数值
  345.            if(y>=3)y=0;
  346.            switch (y)
  347.            {
  348.            case 0:m=1;break;
  349.            case 1:m=5 ;break;
  350.            case 2:m=10 ;break;
  351.            }
  352.            while(keym==0);//自锁
  353.      }
  354.    }
  355. ///换
  356.    if(keyh==0)//上下限转换按键
  357.    {
  358.      delay_50us(100);
  359.      if(keyh==0)
  360.      {
  361.        o++;
  362.               if(o>=3)o=0;//1为上限选中,2为下限选中,0为隐藏
  363.              while(keyh==0);
  364.      }
  365.    }
  366. /////上限         
  367.    if(keyu==0&o==1)//上限加按键
  368.    {
  369.      delay_50us(100);
  370.      if(keyu==0&o==1)
  371.      {
  372.         u=u+m; while(keyu==0);
  373.      }
  374.    }
  375.    if(keyl==0&o==1) //上限减按键

  376.    {
  377.       delay_50us(100);
  378.       if(keyl==0&o==1)
  379.       {
  380.         u=u-m; while(keyl==0);
  381.       }
  382.    }
  383. //// 下限
  384.    if(keyu==0&o==2)//下限加按键
  385.    {
  386.       delay_50us(100);
  387.       if(keyu==0&o==2)
  388.       {
  389.          l=l+m;while(keyu==0);
  390.       }
  391.    }
  392.    if(keyl==0&o==2)//下限减按键
  393.    {
  394.       delay_50us(100);
  395.       if(keyl==0&o==2)
  396.       {
  397.         l=l-m;while(keyl==0);
  398.       }
  399.    }
  400. }

  401. void  BJ()//温度报警子程序
  402. {
  403.           if(f==1)         //温度大于0的温度比较
  404.          {
  405.                
  406.                 if(sdata>=u) //温度大于上限,报警
  407.                 {
  408.                     display(sdata);        button();
  409.                 }
  410.                 else if(l>0&sdata<=l)        //温度小于下限,报警
  411.                 {
  412.                    display(sdata);        button();
  413.                 }
  414.                 else          display(sdata);
  415.          }
  416.          else if(f==0)        //温度小于0的温度比较
  417.          {
  418.                     if(l>=0)
  419.                 {
  420.                     display(sdata);        button();
  421.                 }
  422.                 else if(l<0)        
  423.                 {
  424.                     if(sdata>=-l)  //温度于下限,报警
  425.                                 {
  426.                                          display(sdata);        button();
  427.                                 }
  428.                                 else if(sdata<-l)  //温度大于下限不报警
  429.                                 {
  430.                                      display(sdata);
  431.                                 }
  432.                 }
  433.                 else          display(sdata);                        
  434.          }
  435. }
  436. void main()
  437. {
  438.   buzz=1;
  439.   display0(); //欢迎,
  440.   display1();//框架
  441.   while(1)
  442.   {
  443.      display2(); //上下限,尺度
  444.             ReadTemperature();        //测温程序
  445.          fuhao();//负号显示程序
  446.          key();        //按键
  447.          BJ();        //报警程序
  448.   }

  449. }

复制代码

所有资料51hei提供下载:
18B20温度计1602.rar (2.86 MB, 下载次数: 1239)

评分

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

查看全部评分

回复

使用道具 举报

ID:412814 发表于 2018-11-18 06:34 | 显示全部楼层
真是挺好的资料,下载学习谢谢分享。
回复

使用道具 举报

ID:429055 发表于 2018-11-19 10:47 | 显示全部楼层
刚接触单片机,下载学习,十分感谢
回复

使用道具 举报

ID:317574 发表于 2019-3-24 18:47 | 显示全部楼层
非常感谢楼主的分享,对我十分有用
回复

使用道具 举报

ID:110278 发表于 2019-3-25 09:45 | 显示全部楼层
挺齐全的。
回复

使用道具 举报

ID:424725 发表于 2019-5-4 13:49 | 显示全部楼层
学习学习!!谢谢分享!
回复

使用道具 举报

ID:424725 发表于 2019-5-13 19:50 | 显示全部楼层
谢谢分享!!!!
回复

使用道具 举报

ID:558050 发表于 2019-6-9 10:23 | 显示全部楼层
学习学习!!谢谢分享!
回复

使用道具 举报

ID:661365 发表于 2019-12-11 11:12 | 显示全部楼层
为什么我亮了,但是没有显示呢
回复

使用道具 举报

ID:653079 发表于 2019-12-11 15:44 | 显示全部楼层
有库文件吗
回复

使用道具 举报

ID:663196 发表于 2019-12-16 10:41 | 显示全部楼层
真的很棒   多谢帮忙做完实训程序
回复

使用道具 举报

ID:669610 发表于 2019-12-21 08:57 | 显示全部楼层
ds18b20需要单独的代码调用吗
回复

使用道具 举报

ID:655503 发表于 2019-12-29 21:45 | 显示全部楼层
为什么不报警?
回复

使用道具 举报

ID:673366 发表于 2020-3-18 10:35 | 显示全部楼层
过来学习一下
回复

使用道具 举报

ID:701939 发表于 2020-3-23 17:11 | 显示全部楼层
非常感激楼主的分享
回复

使用道具 举报

ID:680074 发表于 2020-3-23 22:47 | 显示全部楼层
学习学习 很有帮助
回复

使用道具 举报

ID:736392 发表于 2020-4-23 18:48 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:741516 发表于 2020-4-30 11:23 | 显示全部楼层
好用  推荐 解决了好多问题
回复

使用道具 举报

ID:734666 发表于 2020-5-16 17:32 | 显示全部楼层
咋不会报警咧?
回复

使用道具 举报

ID:754720 发表于 2020-5-18 21:50 来自手机 | 显示全部楼层
非常感谢
回复

使用道具 举报

ID:765906 发表于 2020-5-31 21:47 来自手机 | 显示全部楼层
heidianzi520 发表于 2020-5-16 17:32
咋不会报警咧?

我也是   不会报警
回复

使用道具 举报

ID:742468 发表于 2020-6-2 11:47 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:583422 发表于 2020-6-8 09:50 | 显示全部楼层
功能很全
回复

使用道具 举报

ID:775405 发表于 2020-6-10 19:12 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:283691 发表于 2020-6-16 08:42 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:786582 发表于 2020-6-22 14:32 | 显示全部楼层
谢谢楼主分享,正在学习单片机,正好需要模板分析参考
回复

使用道具 举报

ID:722382 发表于 2020-6-26 20:54 | 显示全部楼层
不会报警是因为楼主给proteus原理图的蜂鸣器的连线应该连到2.1端口
回复

使用道具 举报

ID:790639 发表于 2020-6-27 00:48 | 显示全部楼层
感谢楼主分享
回复

使用道具 举报

ID:791057 发表于 2020-6-27 17:51 来自手机 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:779690 发表于 2020-6-27 18:20 | 显示全部楼层
除了报警系统有点问题外,其他的都很好。感谢楼主的分享。
回复

使用道具 举报

ID:780129 发表于 2020-7-1 11:57 | 显示全部楼层
学习不爱我 发表于 2020-6-26 20:54
不会报警是因为楼主给proteus原理图的蜂鸣器的连线应该连到2.1端口

请问一下2.1端口是哪个
回复

使用道具 举报

ID:780129 发表于 2020-7-1 12:01 | 显示全部楼层
转换模式按钮有什么用啊
回复

使用道具 举报

ID:795971 发表于 2020-7-3 18:25 | 显示全部楼层
有Aitium Designer 电路原图吗?  或者在Aitium Designer 中电路仿真的截图吗?谢谢
回复

使用道具 举报

ID:795209 发表于 2020-7-4 11:03 | 显示全部楼层
感谢大佬,很受用
回复

使用道具 举报

ID:795209 发表于 2020-7-4 12:21 | 显示全部楼层
我的proteus是8 pro版本的,有大佬知道为什么我运行程序,lcd显示屏上没有显示出ds18b20设置的温度啊?
回复

使用道具 举报

ID:797455 发表于 2020-7-4 22:47 来自手机 | 显示全部楼层
CHenmo丶 发表于 2020-7-1 11:57
请问一下2.1端口是哪个

能分享一下吗
回复

使用道具 举报

ID:861694 发表于 2020-12-20 09:26 | 显示全部楼层
p2.1端口接R2那儿,蜂鸣器就能响了,不过得等十几秒,感谢楼主和坛友,已成功
回复

使用道具 举报

ID:120677 发表于 2020-12-20 09:59 | 显示全部楼层
好资料,下载学习 提高自己水平
回复

使用道具 举报

ID:862627 发表于 2020-12-20 18:21 | 显示全部楼层
感谢 学到很多
回复

使用道具 举报

ID:882210 发表于 2021-2-2 06:37 | 显示全部楼层
程序思路清晰,值得学习!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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