嵌入式从0到精通——51单片机(四)| DS18B20

前言

DS18B20 是一款常用的单总线数字温度传感器,它没有映射到 51 单片机的片内寄存器,所有控制与数据读取都是通过单总线向传感器发送命令,读取传感器内部暂存寄存器完成。单总线为半双工异步串行通信,仅需一根 GPIO 引脚即可完成 51 单片机与 DS18B20 的数据交互。

传感器参数回顾:

  • 测量量程:-55℃ ~ 125℃
  • 测量精度:±0.5℃
  • 分辨率可选:9/10/11/12bit,最高分辨率 0.0625℃
  • 工作电压:3V‑5.5V

一、DS18B20 核心命令

DS18B20 分为ROM 命令功能存储器命令,51 单片机通过模拟单总线时序发送这些命令控制传感器。

1. ROM 命令

命令码 命令名称 作用说明
0xCC Skip ROM(跳过 ROM) 系统只有 1 片 DS18B20 时使用,跳过 ROM 地址匹配,直接执行后续功能命令;多传感器系统禁止使用该命令

本文为单传感器场景,所以全程使用0xCC跳过 ROM 命令。

2. 存储器功能命令

命令码 命令名称 作用说明
0x44 Convert T 温度转换 启动 DS18B20 进行温度 AD 转换,最大转换时间 750ms,转换结果保存至传感器内部温度寄存器
0xBE Read Scratchpad 读暂存器 读取 DS18B20 内部暂存寄存器,读出的第 1 字节为温度低字节 LSB,第 2 字节为温度高字节 MSB

3.51单片机与ds18b20通信(半双工、异步、串行)

GPIO One-Wire 单总线,传感器通过一根GPIO信号线与单片机通信

二、DS18B20 内部温度寄存器解析

该寄存器位于 DS18B20 传感器内部,不是 51 单片机寄存器,通过0xBE命令读出,一共 2 字节,组成 16 位二进制补码带符号温度数据

寄存器位分配(12 位分辨率)

  • 低字节 LSB:bit0~bit3 为温度小数部分;bit4~bit7 为温度整数的低 4 位
  • 高字节 MSB:bit0~bit3 为温度整数的高 4 位;bit4~bit7 为符号扩展位

分辨率与分度值对照表

配置分辨率 温度最小分度
9 bit 0.5℃
10 bit 0.25℃
11 bit 0.125℃
12 bit 0.0625℃

温度数值换算规则

  1. 正温度 :将拼接完成的 16 位原始数值直接 × 0.0625,得到实际摄氏度。
  2. 负温度 :原始数据是二进制补码,需要对 16 位数做取反+1运算得到绝对值,再 × 0.0625

三、完整工作操作流程(单传感器)

DS18B20 操作有严格时序顺序,顺序出错会读取乱码。

复制代码
1. ds18b20_reset();        //单总线复位,初始化传感器
2. write_ds18b20(0xCC);    //发送跳过ROM命令
3. write_ds18b20(0x44);    //启动温度转换
4. 延时750ms;              //等待AD转换完成

5. ds18b20_reset();        //再次复位
6. write_ds18b20(0xCC);    //再次跳过ROM
7. write_ds18b20(0xBE);    //发送读暂存器命令
8. 读取2字节:LSB、MSB     //获取16位温度补码数据
9. 数据解析换算,得到真实温度

四、单总线底层时序要点(51 GPIO 模拟)

DS18B20 单总线包含:复位时序、写时序、读时序 ,时序时间必须严格遵守,时间不对会通信失败。 单总线具备线与特性;读取数据时主机必须释放总线。

4.1 复位时序(存在脉冲检测)

复制代码
① 主机将总线拉低 480μs ~ 960μs,输出复位脉冲
② 主机释放总线,延时 15μs ~ 60μs
③ DS18B20拉低总线 60μs ~ 240μs,回复响应脉冲(存在脉冲)
④ DS18B20释放总线,总线回到高电平,初始化完成

如果没有检测到响应脉冲,代表传感器未连接或者硬件故障。

4.2 写时序(写 0 / 写 1,write_ds18b20函数底层)

写时序每一位时隙最小 60μs,两次写位之间间隔至少 1μs。

写 0 时序
复制代码
① 主机拉低总线,维持 60μs ~ 120μs
② DS18B20 在 15‑60μs 时间段采样总线,采样为低电平即识别为0
③ 主机释放总线,完成该bit发送
写 1 时序
复制代码
① 主机拉低总线,时间小于15μs,随后立刻释放总线
② DS18B20 在15‑60μs时间段采样总线,采样为高电平即识别为1
③ 总线保持高电平,完成该bit发送

4.3 读时序(读 0 / 读 1,读字节函数底层)

⚠️关键点:主机必须在拉低总线后的 15μs 以内完成电平采样,超过 15μs 电平会失效。

读 1 时序
复制代码
① 主机拉低总线 >1μs,然后释放总线
② DS18B20释放总线,总线为高电平
③ 主机在15μs之内采样总线,读到高电平,代表读取bit=1
读 0 时序
复制代码
① 主机拉低总线 >1μs,然后释放总线
② DS18B20主动把总线拉低,输出0信号
③ 主机在15μs之内采样总线,读到低电平,代表读取bit=0

注意:每读 1bit 都要重复上面的读时隙操作;读字节时,循环 8 次读时序,拼接成 1 字节数据。

五、简单示例伪代码(数据解析片段)

5.1 温度数据解析片段

复制代码
unsigned char LSB,MSB;
int temp_raw;
float temp;

//已经读出LSB、MSB
temp_raw = (MSB << 8) | LSB;   //拼接16位原始补码

if(temp_raw & 0x8000)
{
    //负数处理,补码转真值
    temp_raw = ~temp_raw + 1;
    temp = -(temp_raw * 0.0625f);
}
else
{
    temp = temp_raw * 0.0625f;
}

5.2 写函数伪逻辑

复制代码
void write_ds18b20(unsigned char dat)
{
    unsigned char i;
    for(i=0;i<8;i++)   //低位先发送
    {
        if(dat & 0x01)
        {
            //写1时序
            拉低IO;
            延时<15us;
            释放IO;
        }
        else
        {
            //写0时序
            拉低IO;
            延时60~120us;
            释放IO;
        }
        dat >>= 1;
        延时1us;
    }
}

小结

  1. DS18B20 的温度寄存器在传感器内部,51 单片机通过单总线命令读写,不属于单片机片上寄存器。
  2. 0x44负责启动转换,必须等待转换时间;0xBE读取 2 字节温度补码。
  3. 温度为 16 位二进制补码,根据符号位区分正负,乘以分度值 0.0625 得到实际温度。
  4. 时序是驱动成功的关键,复位、写、读时序时间参数不能随意修改,否则数据出错。
相关推荐
索端阳1 小时前
从时序到代码:51单片机驱动DS18B20温度传感器的深度复盘
51单片机
艾芯微科技2 小时前
ESDUNL24VC1 单向 ESD 静电保护二极管参数、电路设计与 PCB 防护布局
网络·单片机·嵌入式硬件·集成测试·51单片机
M78佐菲11 小时前
51单片机学习笔记:ds18b20要点整理
linux·笔记·嵌入式硬件·学习·51单片机
m0_7527531214 小时前
单片机基础知识
单片机·51单片机
xx~t20 小时前
嵌入式——单片机2
嵌入式硬件·学习·51单片机·串口·蜂鸣器
一直C21 小时前
DS18B20数字温度传感器超详细学习笔记|51单片机单总线通信
51单片机·ds18b20·one-wire
xx~t21 小时前
嵌入式——51单片机3
linux·c语言·嵌入式硬件·51单片机
sunoo-22921 小时前
【51单片机实战】温控下位机完整实现:DS18B20采集 + 自定义二进制串口协议 + PWM声光告
笔记·学习·51单片机·串口
m0_752753121 天前
51单片机中的定时器和中断等
单片机·51单片机