找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机DS18B20数字温度计仿真与源码 LCD1602上显示

  [复制链接]
跳转到指定楼层
楼主
ID:281433 发表于 2018-4-4 13:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STC52单片机控制温度在LCD1602上显示,并且可以控制上下限温度报警,报警提示有灯光和蜂鸣器。开机后有屏幕滚动动态显示,随后进入温度实时监测和上下限设置菜单。并且还有时间显示功能

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


单片机源程序如下:
  1. #include <reg52.H>
  2. #include <intrins.H>
  3. #include <math.h>
  4. #include "eeprom52.h"


  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. uchar a[16]="perchin designed" ;
  8. uchar b[27]="welcome to the world of mcu";

  9. uchar dis_time_buf[16]={1,2,3,4,6,7};


  10. static yemian=0;//(定义变量)
  11. static unsigned char second,minute,hour;
  12. static unsigned char  day=1;
  13. unsigned int tcount;

  14. uchar flat=1;
  15. uchar WenDuS,WenDuX;//报警的温度和湿度
  16. bit flag_300ms ;
  17. uchar TH,TL;
  18. static zd=1;

  19. sbit RS = P0^5;   
  20. sbit LCDEN = P0^7;
  21. sbit rw=P0^6;
  22. sbit  BEEP=P3^6;

  23. sbit led1=P1^0;
  24. sbit led2=P1^1;


  25. sbit K1=P1^2;                //菜单
  26. sbit K2=P1^4;                //上
  27. sbit K3=P1^3;                //下

  28. /*********************************************************
  29. 500us延时函数
  30. 晶振:11.0592MHz
  31. *********************************************************/
  32. void delay500(void)
  33. {
  34.   uchar  i;
  35.   for(i=230;i>0;i--);
  36. }

  37. void delayUs()
  38. {
  39.     _nop_();
  40. }

  41. void delayMs(uint a)
  42. {
  43.     uint i, j;
  44.     for(i = a; i > 0; i--)
  45.         for(j = 100; j > 0; j--);
  46. }

  47. /******************把数据保存到单片机内部eeprom中******************/
  48. void write_eeprom()
  49. {
  50.         SectorErase(0x2000);
  51.          byte_write(0x2000, WenDuS);
  52.         byte_write(0x2001, WenDuX);
  53.         byte_write(0x2060, a_a);        
  54. }

  55. /******************把数据从单片机内部eeprom中读出来*****************/
  56. void read_eeprom()
  57. {
  58.         WenDuS = byte_read(0x2000);
  59.     WenDuX = byte_read(0x2001);
  60.         a_a      = byte_read(0x2060);

  61. }

  62. /**************开机自检eeprom初始化*****************/
  63. void init_eeprom()
  64. {
  65.         read_eeprom();                //先读
  66.         if(a_a != 2)                //新的单片机初始单片机内问eeprom
  67.         {
  68.         WenDuS   = 33;
  69.         WenDuX   = 18;
  70.                 a_a = 2;
  71.                 write_eeprom();
  72.         }        
  73. }


  74. //        lcd配置
  75. int lcd_bz()//测试LCD忙碌状态
  76. {      
  77.          int result ;
  78.          RS = 0 ;
  79.          rw = 1 ;
  80.          LCDEN = 1 ;
  81.          result = (int)(P2 & 0x80) ;
  82.          LCDEN = 0 ;
  83.          return result ;
  84. }

  85. void write_cmd(uchar cmd)// 写指令
  86. {      
  87.          while(lcd_bz()) ;
  88.         RS = 0 ;
  89.         rw = 0 ;
  90.         LCDEN = 0 ;
  91.         P2 = cmd ;
  92.         LCDEN = 1 ;
  93.         LCDEN = 0 ;  
  94. }

  95. void write_addr(uchar addr)//写地址
  96. {      
  97.          write_cmd(addr|0x80) ;
  98. }

  99. void write_byte(uchar dat)//写字节
  100. {      
  101.          while(lcd_bz()) ;
  102.           RS = 1 ;
  103.           rw = 0 ;
  104.           LCDEN = 0 ;
  105.           P2 = dat ;
  106.           LCDEN = 1 ;
  107.           LCDEN = 0 ;
  108. }

  109. void lcd_init()// 初始化
  110. {      
  111.          write_cmd(0x38) ;
  112.          delayMs(1);
  113.          write_cmd(0x08) ;  
  114.          delayMs(1);
  115.          write_cmd(0x01) ;
  116.          delayMs(1);
  117.          write_cmd(0x06) ;
  118.          delayMs(1);
  119.          write_cmd(0x0c) ;
  120.          delayMs(1);
  121. }



  122. void writeComm(uchar comm)
  123. {
  124.      RS = 0;   
  125.     P2 = comm;
  126.     LCDEN = 1;
  127.      delayUs();
  128.     LCDEN = 0;
  129.     delayMs(1);
  130. }

  131. //写数据:RS=1, RW=0;
  132. void writeData(uchar dat)
  133. {
  134.      RS = 1;
  135.      P2 = dat;
  136.      LCDEN = 1;
  137.     delayUs();
  138.     LCDEN = 0;
  139.     delayMs(1);
  140. }


  141. void init()
  142. {
  143.    rw=0;
  144.    writeComm(0x38);
  145.    writeComm(0x0c);
  146.     writeComm(0x06);
  147.     writeComm(0x01);
  148. }

  149. void writeString(uchar * str, uchar length)
  150. {
  151.      uchar i;
  152.     for(i = 0; i < length; i++)
  153.     {
  154.          writeData(str[i]);
  155.      }
  156. }

  157. /**//*****************************DS18B20*******************************/
  158. sbit ds = P3^7;
  159. void dsInit()
  160. {
  161.    
  162.     unsigned int i;  
  163.     ds = 0;
  164.     i = 100;  
  165.      while(i>0) i--;
  166.     ds = 1;   
  167.     i = 4;
  168.      while(i>0) i--;
  169. }

  170. void dsWait()
  171. {
  172.       unsigned int i;
  173.       while(ds);  
  174.       while(~ds);
  175.       i = 4;
  176.       while(i > 0) i--;
  177. }


  178. bit readBit()
  179. {
  180.     unsigned int i;
  181.     bit b;
  182.     ds = 0;
  183.     i++;   
  184.     ds = 1;
  185.    i++; i++;  
  186.     b = ds;
  187.     i = 8;
  188.     while(i>0) i--;
  189.     return b;
  190. }

  191. unsigned char readByte()
  192. {
  193.     unsigned int i;
  194.     unsigned char j, dat;
  195.    dat = 0;
  196.     for(i=0; i<8; i++)
  197.     {
  198.         j = readBit();
  199.       
  200.         dat = (j << 7) | (dat >> 1);
  201.     }
  202.     return dat;
  203. }


  204. void writeByte(unsigned char dat)
  205. {
  206.     unsigned int i;
  207.     unsigned char j;
  208.     bit b;
  209.     for(j = 0; j < 8; j++)
  210.     {
  211.         b = dat & 0x01;
  212.         dat >>= 1;
  213.    
  214.         if(b)   
  215.         {
  216.            ds = 0;          i++; i++;  
  217.             ds = 1;   
  218.             i = 8; while(i>0) i--;  
  219.         }
  220.         else  
  221.         {
  222.             ds = 0;
  223.           i = 8; while(i>0) i--;  
  224.             ds = 1;
  225.            i++; i++;
  226.         }
  227.    }
  228. }


  229. void sendChangeCmd()
  230. {
  231.     dsInit();   
  232.     dsWait();   
  233.     delayMs(1);   
  234.     writeByte(0xcc);
  235.     writeByte(0x44);
  236. }

  237. void sendReadCmd()
  238. {
  239.     dsInit();
  240.     dsWait();
  241.     delayMs(1);
  242.     writeByte(0xcc);
  243.     writeByte(0xbe);
  244. }


  245. int getTmpValue()
  246. {
  247.     unsigned int tmpvalue;
  248.     int value;
  249.     float t;
  250.     unsigned char low, high;
  251.     sendReadCmd();
  252.    
  253.     low = readByte();
  254.     high = readByte();
  255.    
  256.     tmpvalue = high;
  257.     tmpvalue <<= 8;
  258.     tmpvalue |= low;
  259.     value = tmpvalue;
  260.    
  261.   \
  262.     t = value * 0.0625;
  263.     \
  264.     value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5
  265.     return value;
  266. }

  267. void display(int v)
  268. {
  269.     unsigned char count;
  270.     unsigned char datas[] = {0, 0, 0, 0, 0};
  271.     unsigned int tmp = abs(v);
  272.     datas[0] = tmp / 10000;
  273.     datas[1] = tmp % 10000 / 1000;
  274.     datas[2] = tmp % 1000 / 100;
  275.     datas[3] = tmp % 100 / 10;
  276.     datas[4] = tmp % 10;
  277.     writeComm(0xc0+3);
  278.     if(v < 0)
  279.     {
  280.         writeString("- ", 2);
  281.    }
  282.     else
  283.     {
  284.        writeString("+ ", 2);
  285.     }
  286.     if(datas[0] != 0)
  287.     {
  288.         writeData('0'+datas[0]);
  289.     }
  290.     for(count = 1; count != 5; count++)
  291.     {
  292.         writeData('0'+datas[count]);
  293.         if(count == 2)
  294.         {
  295.             writeData('.');
  296.         }
  297.     }
  298. }
  299. /**//*****************************DS18B20*******************************/


  300. //屏幕初始化滚动
  301. void dis_play()
  302. {
  303.         uint i;
  304.     uint j;           
  305.         writeComm(0x00+0x80);
  306.         for(i=0;i<16;i++)
  307.         {
  308.                 writeData(a[i]);        
  309.         }
  310.         writeComm(0x40+0x80);
  311.         for(i=0;i<27;i++)
  312.         {
  313.                 writeData(b[i]);
  314.         }
  315.         writeComm(0x07);         //每写一个数据屏幕就要右移一位,就相对于数据来说就是左移了;
  316.         delayMs(1000) ;
  317.         for(j=0;j<1;j++)                  //首页动态显示
  318.         {        
  319.             
  320.                 writeComm(0x00+0x80);
  321.                 for(i=0;i<16;i++)
  322.                 {
  323.                         writeData(a[i]);
  324.                         delayMs(500);        //如果不加这条延时语句的话滚动会非常快。
  325.                 }
  326.         }
  327. }

  328. void displaysx(uchar addr, uchar q)//在某一地址上显示一字节
  329. {         
  330.          delayMs(1) ;
  331.          write_addr(addr) ;
  332.      write_byte(q) ;
  333.          delayMs(1) ;
  334.          
  335. }


  336. /********************报警程序部分*******************/
  337. void warn(int t)  //报警函数
  338. {
  339.           int x;
  340.           int j;
  341.           x=t/100;

  342.   if(x>=WenDuS)  //检测的温度高于设定温度报警值
  343.                                              
  344.      {
  345.           for(j=200;j>0;j--)
  346.                         {
  347.                                   BEEP=~BEEP;       //输出频率1KHz
  348.                                   delay500();       //延时500us
  349.                                 led1=~led1;
  350.                         }                  
  351.      }      
  352.                  
  353.         if(x<=WenDuX)  //检测的温度低于设定的温度值
  354.                                              
  355.      {
  356.              for(j=200;j>0;j--)
  357.                         {
  358.                                   BEEP=~BEEP;       //输出频率1KHz
  359.                                   delay500();       //延时500us
  360.                                 led2=~led2;
  361.                         }
  362.      }      

  363.                  
  364.         if( x<WenDuS  &&  x>WenDuX )         
  365.     {
  366.                   BEEP=1; //停止报警
  367.                   led1=0;
  368.                   led2=0;
  369.                 }
  370.                  
  371.   
  372. }
  373. ////*****时间********//////////
  374. void LCD_write_char(uchar X,uchar Y,uchar Wdata)
  375. {
  376. uchar address;
  377.   if(Y==0)
  378.     address=0x80+X;//Y=0,表示在第一行显示,地址基数为0x80
  379.   else
  380.     address=0xc0+X;//Y非0时,表时在第二行显示,地址基数为0xC0
  381.   write_cmd(address);//写指令,设置显示初始地址
  382.   write_byte(Wdata);//写入当前字符并显示
  383. }
  384.    void Display_sj(void)
  385. {
  386.     if(tcount==10)
  387.           {tcount=0;
  388.             second++;

  389.                  if(second==60)
  390.                   {second=0;
  391.                    minute++;

  392.                     if(minute==60)
  393.                          {minute=0;
  394.                           hour++;

  395.                           if(hour==24)
  396.                            {hour=0;
  397.                            day++;
  398.                            }
  399.                            if(day==7)
  400.                            {
  401.                                      day=0;
  402.                            }
  403.                          }
  404.                   }
  405.           }
  406.    LCD_write_char(10,0,day+'0');
  407.    //第1行显示     
  408.    LCD_write_char(0,0,hour/10+'0');
  409.    LCD_write_char(1,0,hour%10+'0');                        //时
  410.    LCD_write_char(2,0,':');
  411.    LCD_write_char(3,0,minute/10+1+'0');  
  412.    LCD_write_char(4,0,minute%10+'0');                //分
  413.    LCD_write_char(5,0,':');
  414.    LCD_write_char(6,0,second/10+'0');
  415.    LCD_write_char(7,0,second%10+'0');           //秒         
  416.    
  417. }
  418.         
  419. void main()
  420. {
  421.         
  422.          int i;//i储存转换后的温度值
  423.      sendChangeCmd();
  424.      init();
  425.      writeComm(0x80);
  426.          dis_play();   //屏幕滚动
  427.          init();
  428.      writeComm(0x80);
  429.          init_eeprom();           //读取EEPROM
  430.          led1=0;
  431.          led2=0;
  432.         
  433.          
  434.     while(1)
  435.     {        
  436.                          Display_sj();        
  437.                    tcount++;
  438.         delayMs(70); //温度转换和时间需要 延时确定秒钟时间符合要求
  439.         writeComm(0xc0);
  440.                 i = getTmpValue();
  441.                                 lcd_init(); //初始化                                          
  442.                                 display(i);                        //显示温度
  443.                 sendChangeCmd();
  444.             warn(i);                 //报警函数
  445.                         
  446.                 //====================进入工作状态=======显示温度----时间==========================

  447.                                  displaysx(0x0c,'H');                          //报警最高温度
  448.                            displaysx(0x0d,':');
  449.                            displaysx(0x0e,WenDuS/10+0x30);
  450.                                    displaysx(0x0f,WenDuS%10+0x30);
  451.                                    
  452.                                 displaysx(0x4c,'L');                         //报警最低温度
  453.                 displaysx(0x4d,':');
  454.                                 displaysx(0x4e,WenDuX/10+0x30);  
  455.                         displaysx(0x4f,WenDuX%10+0x30);        

  456.                                                                                           //时间显示
  457.                    //====================K2==0  温度报警上限设置=====进入中断======================
  458.                                 if(K2==0)  //温度
  459.                             {
  460.                                         led1=1;
  461.                                         BEEP=1;
  462.                     led2=0;
  463.                                     delayMs(20);
  464.                           while(led1==1)
  465.                                       {         
  466.                                                          if(K1==0)                         //按键响应结束
  467.                                                                  {
  468.                                                                          led1=0;
  469.                                                                         led2=0;
  470.                                                                         BEEP=1;
  471.                                                                  }                 
  472.                                                          init();
  473.                                                     writeComm(0x80);
  474.                                                     WenDuS=        byte_read(0x2000);           //读取EEPROM
  475.                                                     displaysx(0x0c,'h');                         //报警最高温度
  476.                                                    displaysx(0x0d,':');                 
  477.                                                         displaysx(0x0e,WenDuS/10+0x30);
  478.                                                            displaysx(0x0f,WenDuS%10+0x30);
  479.                                                                   delayMs(10);
  480.                                                                  if(K2==0)
  481.                                                              { delayMs(20);
  482.                                                                         if(K2==0)
  483.                                                               { WenDuS+=1;
  484.                                                                                   byte_write(0x2000, WenDuS);
  485.                                                                if(WenDuS>99) { WenDuS=99; }  //温度上限报警加
  486.                                                                            }
  487.                                                             }
  488.                                                     if(K3==0)
  489.                                                            {
  490.                                                                    delayMs(20);
  491.                                                                         if(K3==0)
  492.                                                                          WenDuS-=1;
  493.                                                                         byte_write(0x2000, WenDuS);
  494.                                                                         if(WenDuS<1) { WenDuS=1; }  //温度下限报警加
  495.                                                                         }
  496.                                                            byte_write(0x2000, WenDuS);                 //保存数据  
  497. ……………………

  498. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
温度计.zip (129.69 KB, 下载次数: 148)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:671057 发表于 2019-12-27 13:47 | 只看该作者
为什么仿真时没反应
回复

使用道具 举报

板凳
ID:673961 发表于 2019-12-27 19:57 来自手机 | 只看该作者
资料很详细。感谢
回复

使用道具 举报

地板
ID:4790 发表于 2019-12-29 20:43 | 只看该作者
1551903521 发表于 2019-12-27 13:47
为什么仿真时没反应

我下了也是没反应,怎莫搞呀。。。
回复

使用道具 举报

5#
ID:757459 发表于 2020-6-3 14:59 | 只看该作者
仿真没有反应,怎么才可以呀
回复

使用道具 举报

6#
ID:281433 发表于 2020-9-15 16:15 | 只看该作者
whtwhtwht 发表于 2019-12-29 20:43
我下了也是没反应,怎莫搞呀。。。

仿真要把程序添加到仿真芯片中(添加程序路径)否则运行仿真没反应。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:835173 发表于 2020-10-27 14:42 | 只看该作者
仿真没有反应,怎么才可以呀
回复

使用道具 举报

8#
ID:281433 发表于 2020-11-4 16:55 | 只看该作者
whtwhtwht 发表于 2019-12-29 20:43
我下了也是没反应,怎莫搞呀。。。

仿真要把程序添加到仿真芯片中(添加程序路径)否则运行仿真没反应。
回复

使用道具 举报

9#
ID:281433 发表于 2020-11-4 16:59 | 只看该作者
各位下载资料后需要将仿真芯片中烧入程序(即在仿真软件中双击51芯片,重新添加程序路径)然后再运行。
回复

使用道具 举报

10#
ID:723182 发表于 2020-11-18 13:05 | 只看该作者
awzlz 发表于 2020-11-4 16:59
各位下载资料后需要将仿真芯片中烧入程序(即在仿真软件中双击51芯片,重新添加程序路径)然后再运行。

添加了程序,加载也没啥也都没有啊
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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