找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机DS18B20温度采集程序,实物成功,但是protues仿真出不来

[复制链接]
跳转到指定楼层
楼主
下面是仿真图:一直显示-0.06,请问这是为什么?

  1. #include <reg52.h>
  2. #include  <INTRINS.H>        
  3. #include  <math.h>    //Keil library  
  4. #include  <stdio.h>   //Keil library
  5. //数据类型定义
  6. #define u8 unsigned char
  7. #define u16  unsigned int
  8. #define uchar unsigned char
  9. #define uint  unsigned int
  10. #define LCD1602_DATAPINS P0//函数声明
  11. void lcd_pos(int pos);
  12. void Delay1ms(u16 c);
  13. void LcdWriteCom(u8 com);
  14. void LcdWriteData(u8 dat);
  15. void LcdInit();
  16. void Multiple_Read_BH1750();    u8 Ds18b20Init();
  17. void Ds18b20WriteByte(u8 dat);
  18. u8 Ds18b20ReadByte();
  19. void  Ds18b20ChangTemp();
  20. void  Ds18b20ReadTempCom();
  21. int Ds18b20ReadTemp();
  22. //I/O口定义
  23. sbit DSPORT = P3^7;
  24. sbit LCD1602_E = P2^7;
  25. sbit LCD1602_RS =P2^6;
  26. sbit LCD1602_RW = P2^5;
  27. sbit LED = P1^2;//定义数据缓冲区
  28. char Disp[30];
  29. char dis_buf[20];
  30. u8    BUF[8];
  31. int     dis_data;

  32. u8 Ds18b20Init()
  33. {
  34.         u8 i;
  35.         DSPORT = 0;                         //将总线拉低480us~960us
  36.         i = 70;        
  37.         while(i--);//延时642us
  38.         DSPORT = 1;                        //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
  39.         i = 0;
  40.         while(DSPORT)        //等待DS18B20拉低总线
  41.         {
  42.                 Delay1ms(1);
  43.                 i++;
  44.                 if(i>5)//等待>5MS
  45.                 {
  46.                         return 0;//初始化失败
  47.                 }
  48.         
  49.         }
  50.         return 1;//初始化成功
  51. }

  52. /*******************************************************************************
  53. * 函 数 名         : Ds18b20WriteByte
  54. * 函数功能                   : 向18B20写入一个字节
  55. * 输    入         : 无
  56. * 输    出         : 无
  57. *******************************************************************************/

  58. void Ds18b20WriteByte(u8 dat)
  59. {
  60.         u16 i, j;

  61.         for(j=0; j<8; j++)
  62.         {
  63.                 DSPORT = 0;                       //每写入一位数据之前先把总线拉低1us
  64.                 i++;
  65.                 DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始
  66.                 i=6;
  67.                 while(i--); //延时68us,持续时间最少60us
  68.                 DSPORT = 1;        //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
  69.                 dat >>= 1;
  70.         }
  71. }
  72. /*******************************************************************************
  73. * 函 数 名         : Ds18b20ReadByte
  74. * 函数功能                   : 读取一个字节
  75. * 输    入         : 无
  76. * 输    出         : 无
  77. *******************************************************************************/


  78. u8 Ds18b20ReadByte()
  79. {
  80.         u8 byte, bi;
  81.         u16 i, j;        
  82.         for(j=8; j>0; j--)
  83.         {
  84.                 DSPORT = 0;//先将总线拉低1us
  85.                 i++;
  86.                 DSPORT = 1;//然后释放总线
  87.                 i++;
  88.                 i++;//延时6us等待数据稳定
  89.                 bi = DSPORT;         //读取数据,从最低位开始读取
  90.                 /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/
  91.                 byte = (byte >> 1) | (bi << 7);                                                  
  92.                 i = 4;                //读取完之后等待48us再接着读取下一个数
  93.                 while(i--);
  94.         }                                
  95.         return byte;
  96. }
  97. /*******************************************************************************
  98. * 函 数 名         : Ds18b20ChangTemp
  99. * 函数功能                   : 让18b20开始转换温度
  100. * 输    入         : 无
  101. * 输    出         : 无
  102. *******************************************************************************/

  103. void  Ds18b20ChangTemp()
  104. {
  105.         Ds18b20Init();
  106.         Delay1ms(1);
  107.         Ds18b20WriteByte(0xcc);                //跳过ROM操作命令                 
  108.         Ds18b20WriteByte(0x44);            //温度转换命令
  109.         //Delay1ms(100);        //等待转换成功,而如果你是一直刷着的话,就不用这个延时了

  110. }
  111. /*******************************************************************************
  112. * 函 数 名         : Ds18b20ReadTempCom
  113. * 函数功能                   : 发送读取温度命令
  114. * 输    入         : 无
  115. * 输    出         : 无
  116. *******************************************************************************/

  117. void  Ds18b20ReadTempCom()
  118. {        

  119.         Ds18b20Init();
  120.         Delay1ms(1);
  121.         Ds18b20WriteByte(0xcc);         //跳过ROM操作命令
  122.         Ds18b20WriteByte(0xbe);         //发送读取温度命令
  123. }
  124. /*******************************************************************************
  125. * 函 数 名         : Ds18b20ReadTemp
  126. * 函数功能                   : 读取温度
  127. * 输    入         : 无
  128. * 输    出         : 无
  129. *******************************************************************************/

  130. int Ds18b20ReadTemp()
  131. {
  132.         int temp = 0;
  133.         u8 tmh, tml;
  134.         Ds18b20ChangTemp();                                 //先写入转换命令
  135.         Ds18b20ReadTempCom();                        //然后等待转换完后发送读取温度命令
  136.         tml = Ds18b20ReadByte();                //读取温度值共16位,先读低字节
  137.         tmh = Ds18b20ReadByte();                //再读高字节
  138.         temp = tmh;
  139.         temp <<= 8;
  140.         temp |= tml;
  141.         return temp;
  142. }
  143. void Delay1ms(u16 c)   //误差 0us
  144. {
  145.     u8 a,b;
  146.         for (; c>0; c--)
  147.         {
  148.                  for (b=199;b>0;b--)
  149.                  {
  150.                           for(a=1;a>0;a--);
  151.                  }      
  152.         }        
  153. }

  154. void LcdWriteCom(u8 com)          //写入命令
  155. {
  156.         LCD1602_E = 0;     //使能
  157.         LCD1602_RS = 0;           //选择发送命令
  158.         LCD1602_RW = 0;           //选择写入
  159.         
  160.         LCD1602_DATAPINS = com;     //放入命令
  161.         Delay1ms(1);                //等待数据稳定

  162.         LCD1602_E = 1;                  //写入时序
  163.         Delay1ms(5);          //保持时间
  164.         LCD1602_E = 0;
  165. }


  166. //*******************************************************************************/                  
  167.                   
  168. void LcdWriteData(u8 dat)                        //写入数据
  169. {
  170.         LCD1602_E = 0;        //使能清零
  171.         LCD1602_RS = 1;        //选择输入数据
  172.         LCD1602_RW = 0;        //选择写入

  173.         LCD1602_DATAPINS = dat; //写入数据
  174.         Delay1ms(1);

  175.         LCD1602_E = 1;   //写入时序
  176.         Delay1ms(5);   //保持时间
  177.         LCD1602_E = 0;
  178. }

  179. /*******************************************************************************
  180. * 函 数 名       : LcdInit()
  181. * 函数功能                 : 初始化LCD屏
  182. * 输    入       : 无
  183. * 输    出       : 无
  184. *******************************************************************************/                  

  185. void LcdInit()                                                  //LCD初始化子程序
  186. {
  187.          LcdWriteCom(0x38);  //开显示
  188.         LcdWriteCom(0x0c);  //开显示不显示光标
  189.         LcdWriteCom(0x06);  //写一个指针加1
  190.         LcdWriteCom(0x01);  //清屏
  191.         LcdWriteCom(0x80);  //设置数据指针起点
  192. }

  193. void lcd_pos(int pos)
  194. {                                    //第一行第几列直接写pos为几,第二行pos从0x40开始
  195.    LcdWriteCom(pos | 0x80) ;   //数据指针=80+地址变量
  196. }

  197. //串口初始化
  198. void UsartInit()
  199. {
  200.         SCON=0X50;                        //设置为工作方式1
  201.         TMOD=0X20;                        //设置计数器工作方式2
  202.         PCON=0X00;                        //波特率加倍
  203.         TH1=0XFD;                                //计数器初始值设置,注意波特率是4800的
  204.         TL1=0XFD;
  205.         ES=1;                                                //打开接收中断
  206.         EA=1;                                                //打开总中断
  207.         TR1=1;                                        //打开计数器
  208. }
  209. //数据转换函数
  210. void display(int temp)         
  211. {
  212.     int m,i;
  213.            float tp;
  214.         int tp1;
  215.                 //温度
  216.         if(temp< 0)                                //当温度值为负数
  217.           {
  218.                 Disp[5] = '-';           
  219.                 temp=temp-1;
  220.                 temp=~temp;
  221.                 tp=temp;
  222.                 temp=tp*0.0625*100+0.5;               
  223.           }
  224.         
  225.          else
  226.           {        
  227.             Disp[5]='+';               
  228.                 tp=temp;
  229.                 temp=tp*0.0625*100+0.5;               
  230.         }
  231.         lcd_pos(0);
  232.         for(m=0;m<6;m++)
  233.          {
  234.           LcdWriteData(Disp[m]);
  235.          }
  236.          Disp[0]='T';
  237.          Disp[1]='E';
  238.          Disp[2]='M';
  239.          Disp[3]='P';
  240.          Disp[4]=':';
  241.          Disp[6]=temp/10000;
  242.          Disp[7]=temp%10000/1000;
  243.          Disp[8]=temp%1000/100;
  244.          Disp[9]=temp%100/10;
  245.          Disp[10]=temp%10;
  246.          if(Disp[6]==0)
  247.      {
  248.             LcdWriteCom(0x86);
  249.             LcdWriteData(' ');
  250.                 if(Disp[7]==0)
  251.                 {
  252.               LcdWriteCom(0x87);
  253.               LcdWriteData(' ');
  254.                 }
  255.                 else
  256.                 {
  257.                  LcdWriteCom(0x87);
  258.              LcdWriteData(Disp[7]+'0');
  259.                 }
  260.          }
  261.          else
  262.          {
  263.           LcdWriteCom(0x86);
  264.           LcdWriteData(Disp[6]+'0');
  265.          }
  266.            LcdWriteCom(0x88);
  267.            LcdWriteData(Disp[8]+'0');
  268.            lcd_pos(10);
  269.            LcdWriteData(Disp[9]+'0');
  270.            LcdWriteCom(0x89);
  271.            LcdWriteData('.');
  272.            lcd_pos(11);
  273.            LcdWriteData(Disp[10]+'0');
  274.            lcd_pos(12);
  275.            LcdWriteData(0xdf);
  276.            lcd_pos(13);
  277.            LcdWriteData('C');        
  278.          Delay1ms(10);
  279. }

  280. //中断服务函数
  281. void Usart() interrupt 4
  282. {
  283. u8 m,n,i;
  284. P1=0x00;
  285. if(RI)
  286. {
  287.   RI=0;
  288.   n=SBUF;        
  289.   if(n==0x30)
  290.   {
  291.    LED=0;
  292.   }
  293.   if(n==0x31)
  294.   {
  295.    LED=1;
  296.   }
  297.   if(n=='B')
  298.   {
  299.    for(m=0;m<7;m++)
  300.    {
  301.     dis_buf[m]=Disp[m+11];
  302.    }
  303.        dis_buf[6]=Disp[17]+'0';
  304.            dis_buf[7]=Disp[18]+'0';
  305.            dis_buf[8]=Disp[19]+'0';
  306.            dis_buf[9]=Disp[20]+'0';
  307.            dis_buf[10]=Disp[21]+'0';
  308.            dis_buf[11]='L';
  309.            dis_buf[12]='x';
  310.            dis_buf[13]=' ';
  311.    for(i=0;i<14;i++)
  312.    {
  313.     SBUF=dis_buf[i];
  314.         while(!TI);
  315.         TI=0;
  316.         Delay1ms(10);
  317.    }
  318.   }
  319.   if(n==0x32)
  320.   {
  321.    for(m=0;m<6;m++)
  322.    {
  323.            dis_buf[m]=Disp[m];
  324.    }
  325.            dis_buf[6]=Disp[6]+'0';
  326.            dis_buf[7]=Disp[7]+'0';
  327.            dis_buf[8]=Disp[8]+'0';
  328.            dis_buf[9]='.';
  329.            dis_buf[10]=Disp[9]+'0';
  330.            dis_buf[11]=Disp[10]+'0';
  331.            dis_buf[12]=' ';
  332.    for(i=0;i<13;i++)
  333.    {
  334.     SBUF=dis_buf[i];
  335.         while(!TI);
  336.         TI=0;
  337.         Delay1ms(10);
  338.    }
  339.   }
  340. }
  341. }
  342. //主函数
  343. void main()
  344. {        
  345.   UsartInit();
  346.   Init_BH1750();       //初始化BH1750
  347.   LcdInit();
  348.   while(1)
  349.   {
  350.    display(Ds18b20ReadTemp());
  351.   }               
  352. }
复制代码

QQ图片20171212204347.png (22.67 KB, 下载次数: 40)

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

使用道具 举报

沙发
ID:190107 发表于 2017-12-12 20:58 | 只看该作者
可能进入死循环了
回复

使用道具 举报

板凳
ID:243501 发表于 2017-12-12 21:21 | 只看该作者
你应该把处理DS18B20采样数据的代码贴出来!
回复

使用道具 举报

地板
ID:260886 发表于 2017-12-12 22:31 | 只看该作者
源程序呢
回复

使用道具 举报

5#
ID:260886 发表于 2017-12-12 22:32 | 只看该作者
代码呢
回复

使用道具 举报

6#
ID:260886 发表于 2017-12-12 22:49 | 只看该作者
代码发出来
回复

使用道具 举报

7#
ID:111634 发表于 2017-12-16 18:34 | 只看该作者
实例97  一线式DS18B20测温
Proteus仿真一下,确认有效。
实例97 DS18B20测温.rar (51.78 KB, 下载次数: 23)

以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。仿真电路和Hex文件能在清华出版社网站免费下载,程序源代码只能到书上看了。到图书馆借,或到新华书店翻阅,或到网上书店打折购买。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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