问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

51单片机DS18B20温度采集实验教程

创作时间:
作者:
@小白创作中心

51单片机DS18B20温度采集实验教程

引用
CSDN
1.
https://m.blog.csdn.net/weixin_72935906/article/details/137791955

一. 任务目标

  1. 学习单总线温度传感器的原理和通信时序;
  2. 使用51单片机的一个 IO 口模拟单总线时序与温度传感器DS18B20通信,将检测的环境温度读取出来。

二、实验要求

  1. 写出实验设计的主要原理。
  2. 使用DS18B20温度传感器、数码管显示检测的温度值,在Proteus和普中开发板实物上完成 DS18B20 的环境温度采集。
  3. 将上述实验成功的代码在Keil中进行仿真运行,使用虚拟逻辑分析仪显示单片机与DS18B20的DQ数据线连接引脚的波形,分析其“初始化–>写—>读”总线时序,与原理进行对比分析:
    1. 判断其是否符合技术要求;
    2. 故意在代码中把时序弄错(改延时delay的延时值),再重新运行之前的实验,看DS18B20是否能正确相应并返回温度。

三、具体实现

3.1 实验原理

DS18B20是由 DALLAS 半导体公司推出的一种的“1-Wire bus(单总线)”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。

想要实现正确工作,一方面是数据,另一方面则是时序。

3.1.1 数据处理

数据方面,将数据存储在相应的RAM中,片内有9个字节的高速暂存器RAM单元,9个字节具体分布如下:

片内有9个字节的高速暂存器RAM单元,9个字节具体分布如下:
第1字节和第2字节是经转换所得的温度值,以两字节补码形式存放其中。
第3、4字节分别是由软件写入用户报警的上下限值TH和TL。
第5个字节为配置寄存器,可对其更改DS18B20的测温分辨率,高速暂存器的
第6、7、8字节未用,为全1。
第9字节是前面所有8个字节的CRC码,用来保证正确通信。片内还有1个E2PROM为TH、TL以及配置寄存器的映像。

存好之后,要将数据进行温度转换,以下是温度转换的计算方法:

  • 当DS18B20采集的温度为+120℃时,输出十六进制数为0x0780。
    =120℃
  • 假如当DS18B20采集的温度为-55℃时,输出为0xfc90,由于是补码,则先将11位数据取反加1得0x0370,注意符号位不变,也不参加运算,则
    =55℃
    注意,负号则需对采集的温度进行判断后,再予以显示。
3.1.2 工作时序

DS18B20的工作时序包括初始化时序、写时序和读时序。

  1. 初始化
    粗黑线为主机。灰色细线为上拉电阻。
    首先主机上拉输入,即DQ=1,延时Delay5(1);
    之后DQ=0,延时480us~ 960us。
    等待存在脉冲的到来,15~60us之后,存在脉冲为1个60到240us的低电平。
    如果没来则按超时处理,从机接收到主机的复位脉冲。
  2. 写时序
    DQ=1,1us;
    DQ=0,若写入0维持不变,1则延时15us,上拉主线,即DQ=1;
  3. 读时序

DQ=1,延时1us;
释放总线,即DQ=0,读数据,如果上拉电阻,读1位数据。若为0,不用管。

3.2 代码实现

实现步骤分别为:
发送启动信号、写入跳过ROM指令、发送温度转换指令、再次启动信号、写入读取温度寄存器指令,然后读取两个字节的温度数据并计算出温度值。

3.2.1 初始化

当DS18B20工作时,首先按照1-Wire协议发送初始化序列,包括发送复位脉冲和存在脉冲。

void init_ds18b20(void)
{
    uchar x=0; 
    DQ =0;    
    delay5(120); 
    DQ =1;    
    delay5(16);
    delay5(80);
}
3.2.2 写入数据

向DS18B20写入一个字节的数据。根据1-Wire协议,写入“1”需要在15微秒内拉低数据线,写入“0”需要拉低60微秒。

void writebyte(uchar dat) 			//函数功能:写1字节
{
    uchar i=0;
    for(i=8;i>0;i--)
    {
         DQ =0;
         DQ =dat&0x01;				//写"1" 在15µs内拉低
         delay5(12);	   			//写"0" 拉低60µs
         DQ = 1;	   
         dat>>=1;
         delay5(5);
         }
}
3.2.3 读数据

从DS18B20读取一个字节的数据。通过发送时钟信号并在15微秒内读取数据线状态来完成每一位的读取。

uchar readbyte(void) 			//函数功能:读取1字节数据
{
    uchar i=0;
    uchar date=0;
    for (i=8;i>0;i--)
    {
          DQ =0;
          delay5(1);
          DQ =1;			//15µs内拉释放总线
          date>>=1;
          if(DQ)
          date|=0x80;
          delay5(11);
     }
     return(date);
}
3.2.4 完整代码

主函数:首先调用delay5函数进行延时,然后进入一个无限循环,在循环中不断地调用retemp函数读取温度,并将其显示在数码管上。通过分时控制两个数码管显示温度的十位和个位。

#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int 
#define out P0
sbit smg1=out^4;
sbit smg2=out^5;
sbit DQ=P3^7;
void delay5(uchar);
void init_ds18b20(void);
uchar readbyte(void);
void writebyte(uchar);
uchar retemp(void);
void main(void)
{
uchar i,temp;
delay5(1000);
while(1)
    {
     temp=retemp();	
     for(i=0;i<10;i++)	//连续扫描数码管10次
     {
     out=(temp/10)&0x0f;
     smg1=0;
     smg2=1;
     delay5(1000);	//延时5ms
     out=(temp%10)&0x0f;
     smg1=1;
     smg2=0;
     delay5(1000);	//延时5ms
     }
    }
}
 /*--------------精确延时5us子程序---------*/	
void delay5(uchar n)
{
     do
     {
     _nop_();
     _nop_();
     _nop_();
     n--;
     }
     while(n);
}
/*--------------初始化函数--------------------*/
void init_ds18b20(void)
{
     uchar x=0; 
     DQ =0;    
     delay5(120); 
     DQ =1;    
     delay5(16);
     delay5(80);
}
/*--------------读取一字节函数----------------*/
uchar readbyte(void)
{
    uchar i=0;
    uchar date=0;
    for (i=8;i>0;i--)
     {
          DQ =0;
          delay5(1);
          DQ =1;	//15微秒内拉释放总线
          date>>=1;
          if(DQ)
          date|=0x80;
          delay5(11);
     }
     return(date);
}
/*--------------写一字节函数------------------*/
void writebyte(uchar dat)
{
 uchar i=0;
 for(i=8;i>0;i--)
     {
      DQ =0;
      DQ =dat&0x01;//写"1" 在15微秒内拉低
      delay5(12);	   //写"0" 拉低60微秒
      DQ = 1;	   
      dat>>=1;
      delay5(5);
      }
}
/*--------------读取温度函数------------------*/
uchar retemp(void)
{
    uchar a,b,tt;
    uint t;
    init_ds18b20();
    writebyte(0xCC); 
    writebyte(0x44);
    init_ds18b20();
    writebyte(0xCC); 
    writebyte(0xBE); 
    a=readbyte();
    b=readbyte();
    t=b;
    t<<=8;
    t=t|a;
    t= t*0.0625;
    return(tt);
}
3.2.5 仿真结果

3.3 时序分析

3.3.1 波形图

经过分析后发现符合符合技术要求。

3.3.2 更改时序

找到初始化函数,更改delay5函数的变量。

结果如下:

我们发现,更改数据后,无法正确相应并返回温度。因此,时序对于DS18B20采集环境是至关重要的。

四、实验总结

通过实验,我们发现时序对于DS18B20采集环境是至关重要的。

当我们觉察到温度采集的滞后时,可以尝试更改delay相关参数。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号