第六讲DS18B20模块

这份总结包含了 硬件原理、通信时序、代码逻辑、数据换算避坑指南。建议直接复制到 Typora 里,考前看一遍,稳过!:memo:


DS18B20 终极复盘手册

核心特征:单总线 (1-Wire) 通信,对延时精度要求极高,数据以 16位 二进制补码存储,默认精度 12位 (0.0625°C)。

1. 硬件物理层 (The Hardware)

  • 通信接口DQ (Data Request)
    • 单总线:只有一根数据线,没有时钟线。通信靠“拉低电平的时间长短”来区分 0 和 1。
  • 关键电路上拉电阻 (Pull-up Resistor)
    • 原因:DQ 引脚是 开漏输出 (Open Drain),只能拉低,无法推高。
    • 作用:平时将总线维持在 高电平 (1)。单片机和传感器谁都不说话时,线上就是高电平。
  • 供电模式:蓝桥杯板子上通常使用 外部供电 (VDD接5V),不使用寄生电源模式。

2. 软件时序层 (The Timing)

通信全靠微秒级的延时,必须严格遵守。

2.1 初始化 (握手)

这是所有操作的第一步,检测设备是否存在。

  1. 复位脉冲:主机拉低总线至少 480µs
  2. 释放总线:主机拉高,等待 15-60µs
  3. 存在脉冲:DS18B20 拉低总线 60-240µs (代表“我在”)。

2.2 写时序 (Write Slot)

  • 写 0:主机拉低 > 60µs (按住不放)。
  • 写 1:主机拉低 < 15µs 然后立马松手 (点一下)。

2.3 读时序 (Read Slot)

  • 主机先拉低 > 1µs,然后立刻释放,随即读取 I/O 口电平。
  • 注意:要在 15µs 内读取完毕。

:warning: 比赛大坑
蓝桥杯现在的板子是 STC15 (1T模式),速度很快。官方提供的 Delay_OneWire 函数如果还是旧版 t *= 12 (STC89 模式),延时会不够,导致通信失败。请务必检查并适配官方驱动!


3. 操作流程逻辑 (The Logic)

铁律:每次执行新功能,都要重新走一遍 “初始化 → ROM指令 → 功能指令” 的流程。

3.1 常用指令代码 (死记)

  • 0xCCSkip ROM (跳过ROM)。因为板子上只有一个设备,不查身份证,直接群发。
  • 0x44Convert T (温度转换)。命令芯片开始测温。
  • 0xBERead Scratchpad (读暂存器)。命令芯片吐出数据。

3.2 标准代码流程

// --- 第一阶段:下令干活 ---
Init_DS18B20();        // 1. 复位
Write_DS18B20(0xCC);   // 2. 跳过 ROM
Write_DS18B20(0x44);   // 3. 开始转换 (需要等待时间)

// --- 第二阶段:获取结果 ---
Init_DS18B20();        // 1. 再次复位 (必须!)
Write_DS18B20(0xCC);   // 2. 跳过 ROM
Write_DS18B20(0xBE);   // 3. 读暂存器

low  = Read_DS18B20(); // 4. 先读低 8 位 (LSB)
high = Read_DS18B20(); // 5. 后读高 8 位 (MSB)

4. 数据换算 (The Math)

4.1 数据结构

DS18B20 默认精度 12位,数据存放在两个字节中:

  • Byte 0 (LS Byte): 低8位
  • Byte 1 (MS Byte): 高8位 (前5位是符号位 S)

4.2 计算公式

  • 分辨率0.0625°C (即 $1/16$)。

  • 合成原始数据

    unsigned int temp_raw = (high << 8) | low;
    
  • 转为实际温度 (float)

    float temp_float = temp_raw * 0.0625; 
    // 或者
    float temp_float = temp_raw / 16.0;
    
  • 数码管显示 (整数法)
    如果要显示一位小数,通常将结果放大 10 倍:

    unsigned int display_val = temp_raw * 10 / 16;
    // 比如 25.5度 -> temp_raw计算后 -> display_val = 255
    

5. 避坑指南 (Troubleshooting)

现象 原因 解决方案
上电显示 85°C 这是出厂默认值。说明还没转换完成就读取了。 1. 忽略第一次读取的值。2. 明白转换需要 750ms
读数全是 0 或 255 通信失败。 1. 检查 Init 是否成功。2. 检查延时函数是否适配 STC15。3. 检查引脚是否定义对 (P1.4)。
温度显示 4095 同上,通常是线没接好或延时太短,读出来全是 1。 检查上拉电阻和延时。
数码管乱跳 读取频率太快或有中断打断了 1-Wire 时序。 1. 在读取时暂时关闭中断 EA=0 (慎用)。2. 延时函数要准。
报错 Unresolved External 函数名大小写不一致。 检查 .c 和 .h 以及调用处,必须一模一样。