找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9922|回复: 7
收起左侧

51单片机-ds18b20多点温度采集proteus仿真-lcd1602显示 源码都有还可以读序列号

  [复制链接]
ID:137190 发表于 2016-9-9 22:53 | 显示全部楼层 |阅读模式
51单片机做的多点温度采集系统的仿真,带源码
0.png
0.png

全部资料下载:
51单片机-ds18b20多点采集-lcd1602显示.zip (56.56 KB, 下载次数: 290)


lcd1602显示ds18b20读温度程序:
  1. #include<reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit lcdrs=P3^0;
  5. sbit lcdrw=P3^1;
  6. sbit lcden=P3^2;

  7. sbit DQ=P1^7;
  8. uint value;
  9. uchar code table1[]={0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e};//rom1       测得的序列号
  10. uchar code table2[]={0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9};//rom2
  11. uchar code table3[]="Temple";
  12. bit fg=0;
  13. void delay(uint n)
  14. {  uint x,y;
  15.    for(x=n;x>0;x--)
  16.        for(y=110;y>0;y--);
  17. }

  18. void write_com(uchar com)
  19. {
  20.         lcdrs=0;                        //rs=0时输入指令
  21.         P2=com;
  22.         delay(5);
  23.         lcden=1;                        //en=1时读取信息
  24.         delay(5);
  25.         lcden=0;                        //1 -> 0 执行指令
  26. }


  27. void write_dat(uchar dat)
  28. {
  29.         lcdrs=1;                         //rs=1时输入数据
  30.         P2=dat;
  31.         delay(5);
  32.         lcden=1;
  33.         delay(5);
  34.         lcden=0;
  35. }

  36. void init_lcd()
  37. {
  38.         lcden=0;
  39.         lcdrw=0;
  40.         write_com(0x38);          //8位数据,双列,5*7字形
  41.         write_com(0x0c);         //开启显示屏,关光标,光标不闪烁
  42.         write_com(0x06);         //显示地址递增,即写一个数据后,显示位置右移一位
  43.         write_com(0x01);

  44. }

  45. void delay_us(uchar t)//微妙延时
  46. {
  47.         while(t--);
  48. }
  49. void init_ds18b20()        //数据初始化
  50. {
  51.         DQ=1;
  52.         delay_us(4);
  53.         DQ=0;
  54.         delay_us(80);
  55.         DQ=1;
  56.         delay_us(200);
  57. }
  58. void write_ds18b20(uchar dat) //写数据
  59. {
  60.         uchar i;
  61.         for(i=0;i<8;i++)
  62.         {
  63.                 DQ=0;               
  64.                 DQ=dat&0x01;
  65.                 delay_us(15);
  66.                 DQ=1;
  67.                 dat=dat>>1;
  68.         }
  69.         delay_us(10);
  70. }
  71. uchar read_ds18b20()  //读数据
  72. {
  73.         uchar i=0,readat=0;
  74.         for(i=0;i<8;i++)
  75.         {
  76.                 DQ=0;
  77.                 readat=readat>>1;      //八位全部都是0,向右移一位后,仍然全是0
  78.                 DQ=1;
  79.                 if(DQ)                //如果DQ为1,readat进行或运算,如果为0,则子语句不执行,直接for循环此时采集的数据是0
  80.                         readat=readat|0x80;//此时最高位为1         ,然后再进行for循环 最高位成为第七位,依次往复
  81.                 delay_us(10);
  82.         }
  83.         return readat;
  84. }

  85. void check_rom(uchar a)                   //匹配序列号
  86. {
  87.         uchar j;

  88.            write_ds18b20(0x55);
  89.         if(a==1)
  90.         {
  91.                 for(j=0;j<8;j++)
  92.                 {
  93.                         write_ds18b20(table1[j]);
  94.                 }
  95.         }
  96.         if(a==2)
  97.         {
  98.                 for(j=0;j<8;j++)
  99.                 {
  100.                         write_ds18b20(table2[j]);
  101.                 }
  102.         }

  103. }

  104. uchar change_ds18b20(uchar z)
  105. {
  106.         uchar tl,th;
  107.         
  108.         init_ds18b20();              //初始化
  109.         write_ds18b20(0xcc);  //跳过
  110.         init_ds18b20();                  
  111.         if(z==1)
  112.         {
  113.                 check_rom(1);           //         匹配rom1
  114.         }
  115.         if(z==2)
  116.         {
  117.                 check_rom(2);           //          匹配rom2
  118.         }

  119.         write_ds18b20(0x44);
  120.         init_ds18b20();
  121.         write_ds18b20(0xcc);
  122.         init_ds18b20();
  123.         if(z==1)
  124.         {
  125.                 check_rom(1);           //
  126.         }
  127.         if(z==2)
  128.         {
  129.                 check_rom(2);           //
  130.         }

  131.         write_ds18b20(0xbe);  //启动读暂存器。读内部ram中9字节温度数据
  132.         tl=read_ds18b20();
  133.         th=read_ds18b20();
  134.         value=th;
  135.         value=value<<8;
  136.         value=value|tl;
  137.         if(th < 0x80)
  138.         {        fg=0;  }

  139.         
  140.         if(th>= 0x80)
  141.         {        fg=1;
  142.                  
  143.                 value=~value+1;
  144.         }
  145.                 value=value*(0.0625*10);
  146.             return value;
  147.         
  148. }

  149. void display_lcd1602(uchar z)
  150. {         
  151.          uchar i;
  152.          if(z==1)
  153.          {
  154.                  write_com(0x80);
  155.                  for(i=0;i<6;i++)
  156.                  {
  157.                          write_dat(table3[i]);
  158.                         delay(3);
  159.                  }
  160.                  write_dat(0x2d);
  161.                  write_dat(0x41);
  162.                  write_dat(0x3a);
  163.                  if(fg==1)
  164.                  {
  165.                          write_dat(0xb0);
  166.                  }
  167.                  if(fg==0)
  168.                  {
  169.                          write_dat(0x20);
  170.                  }
  171.                  write_dat(value/100+0x30);
  172.                  write_dat(value%100/10+0x30);
  173.                  write_dat(0x2e);
  174.                  write_dat(value%10+0x30);
  175.                  write_dat(0xdf);
  176.                  write_dat(0x43);
  177.          }

  178.          if(z==2)
  179.          {
  180.                  write_com(0x80+0x40);
  181.                  for(i=0;i<6;i++)
  182.                  {
  183.                          write_dat(table3[i]);
  184.                         delay(3);
  185.                  }
  186.                  write_dat(0x2d);
  187.                  write_dat(0x42);
  188.                  write_dat(0x3a);
  189.                  if(fg==1)
  190.                  {
  191.                          write_dat(0xb0);
  192.                  }
  193.                  if(fg==0)
  194.                  {
  195.                          write_dat(0x20);
  196.                  }  
  197.                  write_dat(value/100+0x30);
  198.                  write_dat(value%100/10+0x30);
  199.                  write_dat(0x2e);
  200.                  write_dat(value%10+0x30);
  201.                  write_dat(0xdf);
  202.                  write_dat(0x43);
  203.          }


  204. }

  205. void main()
  206. {
  207.         init_lcd();

  208.         while(1)
  209.         {
  210.                 change_ds18b20(1);
  211.                 display_lcd1602(1);
  212.                
  213.                 change_ds18b20(2);
  214.                 display_lcd1602(2);
  215.                                        
  216.         }
  217. }
复制代码

lcd1602显示ds18b20温度采集读序列号程序
  1. #include<reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit lcdrs=P3^0;
  5. sbit lcdrw=P3^1;
  6. sbit lcden=P3^2;

  7. sbit DQ=P1^7;
  8. uint value;
  9. uchar save_number[8];

  10. void delay(uint n)
  11. {  uint x,y;
  12.    for(x=n;x>0;x--)
  13.        for(y=110;y>0;y--);
  14. }

  15. void write_com(uchar com)
  16. {
  17.         lcdrs=0;                        //rs=0时输入指令
  18.         P2=com;
  19.         delay(5);
  20.         lcden=1;                        //en=1时读取信息
  21.         delay(5);
  22.         lcden=0;                        //1 -> 0 执行指令
  23. }


  24. void write_dat(uchar dat)
  25. {
  26.         lcdrs=1;                         //rs=1时输入数据
  27.         P2=dat;
  28.         delay(5);
  29.         lcden=1;
  30.         delay(5);
  31.         lcden=0;
  32. }

  33. void init_lcd()
  34. {
  35.         lcden=0;
  36.         lcdrw=0;
  37.         write_com(0x38);          //8位数据,双列,5*7字形
  38.         write_com(0x0c);         //开启显示屏,关光标,光标不闪烁
  39.         write_com(0x06);         //显示地址递增,即写一个数据后,显示位置右移一位
  40.         write_com(0x01);

  41. }



  42. void delay_us(uchar t)//微秒延时
  43. {
  44.         while(t--);
  45. }
  46. void init_ds18b20()        //数据初始化
  47. {
  48.         DQ=1;
  49.         delay_us(4);
  50.         DQ=0;
  51.         delay_us(80);
  52.         DQ=1;
  53.         delay_us(200);
  54. }
  55. void write_ds18b20(uchar dat) //写数据
  56. {
  57.         uchar i;
  58.         for(i=0;i<8;i++)
  59.         {
  60.                 DQ=0;               
  61.                 DQ=dat&0x01;
  62.                 delay_us(15);
  63.                 DQ=1;
  64.                 dat=dat>>1;
  65.         }
  66.         delay_us(10);
  67. }
  68. uchar read_ds18b20() //读数据
  69. {
  70.         uchar i=0,readat=0;
  71.         for(i=0;i<8;i++)
  72.         {
  73.                 DQ=0;
  74.                 readat=readat>>1;   //八位全部都是0,向右移一位后,仍然全是0
  75.                 DQ=1;
  76.                 if(DQ)             //如果DQ为1,readat进行或运算,如果为0,则子语句不执行,直接for循环此时采集的数据是0
  77.                         readat=readat|0x80;//此时最高位为1         ,然后再进行for循环 最高位成为第七位,依次往复
  78.                 delay_us(10);
  79.         }
  80.         return readat;
  81. }

  82. uchar change_ds18b20()
  83. {
  84.         uchar tl,th;
  85.         init_ds18b20();              //初始化
  86.         write_ds18b20(0xcc);  //跳过rom
  87.         write_ds18b20(0x44);  //启动ds18b20进行温度转换,结果存入9字节ram中

  88.         init_ds18b20();                  //?  缺少不可执行
  89.         write_ds18b20(0xcc);
  90.         write_ds18b20(0xbe);  //启动读暂存器。读内部ram中9字节温度数据
  91.         tl=read_ds18b20();
  92.         th=read_ds18b20();
  93.         value=th;
  94.         value=value<<8;
  95.         value=value|tl;
  96.         value=value*(0.0625*10)+0.5;
  97.         return value;
  98. }


  99. void dis_readnumber()                                         
  100. {
  101.         uchar i,temp;

  102.         init_ds18b20();

  103.         write_ds18b20(0x33);                     //读rom   即rom中的编码
  104.         for(i=0;i<8;i++)
  105.         {
  106.                 save_number[i]=read_ds18b20();  //保存序列号
  107.         }

  108.     write_com(0x80);                                    
  109.         for(i=0;i<8;i++)
  110.         {
  111.                 temp=save_number[i]>>4;
  112.                 if(temp<10)
  113.                 {
  114.                         write_dat(0x30+temp);
  115.                 }
  116.                 else
  117.                 {
  118.                          write_dat(0x37+temp);
  119.                 }

  120.                 temp=save_number[i]&0x0f;
  121.                 if(temp<10)
  122.                 {
  123.                         write_dat(0x30+temp);
  124.                 }
  125.                 else
  126.                 {
  127.                          write_dat(0x37+temp);
  128.                 }
  129.         }

  130. }
  131. void main()
  132. {
  133.         init_lcd();
  134.         while(1)
  135.         {
  136.            dis_readnumber();    //显示序列号
  137.         }
  138. }
复制代码

回复

使用道具 举报

ID:122547 发表于 2017-6-26 19:16 | 显示全部楼层
看起来不错啊 比我的 高大上
回复

使用道具 举报

ID:218630 发表于 2018-3-5 22:45 | 显示全部楼层
proteus中的传感器的序列号只有6个数字,lz这个长的是要设置过吗
回复

使用道具 举报

ID:311217 发表于 2018-4-18 20:57 | 显示全部楼层
很棒啊
回复

使用道具 举报

ID:294657 发表于 2019-4-28 14:57 | 显示全部楼层
想请问protues中ds18b20的ROm怎么设置 实际检测出来的ROM有16位 而仿真里面只能填写6位
回复

使用道具 举报

ID:703703 发表于 2020-3-16 11:49 | 显示全部楼层
为什么我拿过来后显示不了温度呢?
回复

使用道具 举报

ID:423911 发表于 2021-9-28 19:48 | 显示全部楼层
正在找这个资料,感谢
回复

使用道具 举报

ID:440028 发表于 2022-1-6 08:51 | 显示全部楼层
感谢你,正在学习中,多路检测正发愁那
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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