51单片机(四)DS18B20 数字温度传感器

1. 引言

DS18B20 是 DALLAS 公司(现属 Maxim Integrated)生产的一款单总线数字温度传感器,因其接口简单、精度高、支持多点组网等特性,被广泛应用于工业控制、环境监测、智能家居等场景。本文将从参数指标、内部结构、通信协议、上拉电阻与线与特性、采集流程以及通信时序六个方面,对 DS18B20 进行系统讲解。

2. DS18B20 参数指标

DS18B20 的核心参数如下:

  • 量程(温度测量范围):-55℃ ~ +125℃
  • 精度:在 -10℃ ~ +85℃ 范围内,典型误差为 ±0.5℃
  • 分辨率 :可通过配置寄存器选择,默认 12 位
    • 9 位:0.5℃(转换时间 93.75ms)
    • 10 位:0.25℃(187.5ms)
    • 11 位:0.125℃(375ms)
    • 12 位(默认):0.0625℃(750ms)
  • 工作电压:3.0V ~ 5.5V
  • 通信接口:单总线(One-Wire),半双工、串行、异步

3. 芯片内部结构

DS18B20 内部主要由以下模块组成:

  • 64 位 ROM 与单总线接口:每个芯片拥有唯一的 64 位序列号,用于多点组网时寻址
  • 存储器逻辑控制:协调芯片内部各模块的工作时序
  • 暂存器(Scratchpad):存放温度转换结果、配置参数、高温/低温触发阈值
  • 温度传感器:核心测温单元
  • 高温触发阈值(TH)与低温触发阈值(TL):可配置,用于报警
  • 8 位 CRC 校验生成器:为通信数据提供校验

4. 上拉电阻与线与特性

DS18B20 采用单总线通信,总线空闲时必须保持高电平。因此,在 DQ 数据线与 VCC 之间需要外接一个 4.7kΩ(典型值)的上拉电阻

线与特性

当主机(如 51 单片机)和 DS18B20 都释放总线时,总线由上拉电阻拉为高电平。主机与 DS18B20 的引脚电平关系遵循「线与」逻辑:

主机电平 DS18B20 电平 总线电平
0 0 0
0 1 0
1 0 0
1 1 1

当主机或 DS18B20 需要作为数据接收方时,必须释放总线(将引脚置为高阻输入态),让上拉电阻将总线拉高。

5. 通信协议

DS18B20 使用单总线(One-Wire)协议进行半双工、异步、串行通信。所有数据读写均通过 DQ 引脚完成。

温度数据格式

温度值以 16 位、符号扩展的二进制补码 形式存储,通过单总线串行发出。默认 12 位分辨率下,每个 LSB 代表 0.0625℃。

6. 采集流程

读取 DS18B20 温度的完整流程如下:

  1. 复位:主机发送复位脉冲,等待 DS18B20 响应
  2. 发送 0xCC:跳过 ROM(单点采集时使用,多点需发送匹配 ROM 命令)
  3. 发送 0x44:启动温度转换
  4. 延时 750ms:等待转换完成(12 位分辨率下)
  5. 复位:再次复位
  6. 发送 0xCC:跳过 ROM
  7. 发送 0xBE:读取暂存器(读温度)
  8. 读取两个字节:低字节在前,高字节在后,拼接得到 16 位温度值

7. 通信时序详解

7.1 复位时序

复位是单总线通信的起始信号,时序如下:

  1. 主机将总线拉低 480μs ~ 960μs,发送复位脉冲
  2. 主机释放总线,总线由上拉电阻拉为高电平
  3. DS18B20 检测到总线高电平后,等待 15μs ~ 60μs
  4. DS18B20 将总线拉低 60μs ~ 240μs,回复响应脉冲
  5. DS18B20 释放总线,总线恢复高电平,初始化完成

7.2 写时序

写时序分为写 '0' 和写 '1' 两种:

写 '0' 时序:

  1. 主机将总线拉低 60μs(最长 120μs)
  2. DS18B20 在 30μs ~ 60μs 内采样,若总线为低电平,则读到 '0'
  3. 主机释放总线,总线恢复高电平

写 '1' 时序:

  1. 主机将总线拉低 小于 15μs ,然后释放总线,总线被拉高

  2. DS18B20 在拉高后的 45μs 内 采样,若总线为高电平,则读到 '1'

7.3 读时序

读时序也分为读 '0' 和读 '1':

读 '1' 时序:

  1. 主机拉低总线,持续 1μs,释放总线
  2. DS18B20 释放总线,总线由上拉电阻拉为高电平
  3. 主机在 15μs 内 采样,此时总线为高电平,读到 '1'

读 '0' 时序:

  1. 主机拉低总线,持续 1μs ,释放总线

  2. DS18B20 在主机释放总线后,主动拉低总线(表示传输 '0')

  3. 主机在 15μs 内 采样,此时总线为低电平,读到 '0'

8. 代码实现示例

以下基于 51 单片机(C51)给出 DS18B20 驱动代码的核心函数:

c 复制代码
// 复位函数
unsigned char ds18b20_reset(void)
{
    unsigned char presence;
    DQ = 0;          // 拉低总线
    Delay480us();    // 延时 480μs
    DQ = 1;          // 释放总线
    Delay60us();     // 等待 60μs
    presence = DQ;   // 读取响应脉冲
    Delay240us();    // 等待时序结束
    return presence; // 0=存在,1=无响应
}

// 写一个字节
void ds18b20_write_byte(unsigned char dat)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        DQ = 0;          // 拉低总线,启动写时序
        if (dat & 0x01)  // 写 '1'
        {
            DQ = 1;      // 释放总线,拉高
        }
        // 写 '0' 则保持低电平
        Delay60us();     // 保持 60μs
        DQ = 1;          // 释放总线
        dat >>= 1;
    }
}

// 读一个字节
unsigned char ds18b20_read_byte(void)
{
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++)
    {
        DQ = 0;          // 拉低总线,启动读时序
        _nop_();         // 短暂延时
        _nop_();
        DQ = 1;          // 释放总线
        _nop_();
        _nop_();
        _nop_();
        if (DQ)          // 采样,高电平为 '1'
        {
            dat |= (0x01 << i);
        }
        Delay10us(6);    // 等待读时序结束
    }
    return dat;
}

// 采集温度(完整流程)
float ds18b20_get_temperature(void)
{
    unsigned char low, high;
    short temp_raw;
    float temperature;

    ds18b20_reset();
    ds18b20_write_byte(0xCC);  // 跳过 ROM
    ds18b20_write_byte(0x44);  // 启动温度转换
    Delay750ms();              // 等待转换完成

    ds18b20_reset();
    ds18b20_write_byte(0xCC);  // 跳过 ROM
    ds18b20_write_byte(0xBE);  // 读取暂存器

    low  = ds18b20_read_byte(); // 低字节
    high = ds18b20_read_byte(); // 高字节

    temp_raw = (high << 8) | low;  // 拼接 16 位补码
    temperature = temp_raw * 0.0625; // 12 位分辨率下转换

    return temperature;
}

9. 总结

DS18B20 凭借单总线接口、宽电压范围、高精度以及多点组网能力,成为嵌入式温度采集的首选方案。理解其复位时序、读写时序以及完整的采集流程,是正确驱动该传感器的关键。实际应用中,注意上拉电阻的选型(典型 4.7kΩ)和延时时间的精确控制,可有效提高通信稳定性。

相关推荐
2401_827501281 小时前
51单片机(三)串口通信(UART)、Modbus协议
单片机·嵌入式硬件·51单片机
不会c+3 小时前
C语言:入门到精通(408考研版)系列七 派生的数据类型
c语言·开发语言
躺不平的理查德3 小时前
SQLite C API 备忘录
c语言·数据库·sqlite
程序猿编码4 小时前
没有AI框架,没有GPU,一个C语言文件跑通大模型
c语言·开发语言·人工智能·深度学习·ai·大模型
CHANG_THE_WORLD5 小时前
Linux C 多线程 TCP 并发服务器:从 `accept()` 到资源管理深度剖析
linux·服务器·c语言
十月的皮皮6 小时前
C语言学习笔记20260716-编译与链接
c语言·笔记·学习
牧以南歌〆6 小时前
数据结构<一>顺序表
c语言·数据结构·算法
CHANG_THE_WORLD6 小时前
Linux C 多线程 TCP 并发服务器:从 `accept()` 到工作线程的完整解析
linux·服务器·c语言
敲上瘾6 小时前
Linux系统调用mmap文件映射与malloc简单模拟实现指南
linux·服务器·c语言·缓存