学习笔记——DS18B20 温度传感器

DS18B20 温度传感器

一、传感器概述

1.1 基本特性

DS18B20 是由 Dallas Semiconductor(现 Maxim Integrated)生产的数字温度传感器。该器件采用单总线接口,可直接输出数字温度值,无需外部模数转换电路。

关键参数表

参数类别 技术规格
温度测量范围 -55℃ 至 +125℃
测量精度 ±0.5℃(-10℃ 至 +85℃范围内)
分辨率 可编程配置:9、10、11、12 位
默认分辨率 12 位(0.0625℃/LSB)
工作电压 3.0V 至 5.5V
转换时间 93.75ms(9位)至 750ms(12位)
封装形式 TO-92、SO-8、µSOP

1.2 引脚定义

TO-92 封装引脚排列(正视,引脚朝下):

引脚功能说明

  • 引脚1(GND):电源地,连接至系统参考地

  • 引脚2(DQ):单总线数据输入/输出引脚

  • 引脚3(VDD):电源输入引脚(3.0V-5.5V)

二、单总线通信协议

2.1 协议概述

单总线协议(1-Wire Protocol)采用单根数据线实现双向通信。该协议包含以下关键技术特性:

  1. 单主多从架构:单总线上可挂接多个从设备

  2. 寄生供电模式:通过数据线为设备供电,无需独立电源

  3. 严格的时序要求:所有通信操作都有精确的时序规范

2.2 电气特性

复制代码
典型应用电路:
VCC (+3.3V-5V)
  │
  ├─[4.7kΩ]─┐
  │         │
  └─────┐   │
        │   │
      DS18B20 │
       1│ 2│ 3│
       GND DQ VDD
        │   │
       GND  ├─→ MCU I/O Pin
            │
           GND

上拉电阻作用

  • 在总线空闲时提供确定的高电平状态

  • 确保信号完整性,减少噪声影响

  • 典型值:4.7kΩ ±5%

三、温度数据格式

3.1 温度寄存器结构

DS18B20 输出 16 位二进制补码格式的温度数据:

位位置 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
含义 S S S S S 2⁶ 2⁵ 2⁴ 2⁰ 2⁻¹ 2⁻² 2⁻³ 2⁻⁴

说明

  • 位 15-11:符号位(S=1 表示负温度,S=0 表示正温度)

  • 位 10-4:整数部分(7 位二进制,范围 0-127)

  • 位 3-0:小数部分(4 位二进制)

3.2 分辨率配置

DS18B20 提供四种分辨率设置,通过配置寄存器实现:

分辨率位数 R1 R0 温度精度 最大转换时间
9 位 0 0 0.5℃ 93.75ms
10 位 0 1 0.25℃ 187.5ms
11 位 1 0 0.125℃ 375ms
12 位 1 1 0.0625℃ 750ms

默认配置:R1=1, R0=1(12 位分辨率)

四、通信时序详析

4.1 复位脉冲时序

复制代码

时间参数要求

  • 主机复位脉冲宽度:最小 480μs

  • 主机释放总线后延迟:15-60μs

  • 从机响应脉冲宽度:60-240μs

  • 总线恢复时间:最小 480μs

4.2 写时序规范

写"0"时序

  • 主机将总线拉低至少60us

  • ds18b20在60us内去采样,采到低电平,则代表主机向ds18b20发送了一个bit'0'

  • 最后主机将总线拉高

写"1"时序

  • 主机将总线拉低大于1us

  • 主机释放总线,将总线拉高

  • 主机延时至少45us,确保ds18b20能够采样到一个高电平

写时间槽参数

  • 写"0"低电平时间:60-120μs

  • 写"1"低电平时间:1-15μs

  • 写周期总时间:最小 60μs,典型 70μs

4.3 读时序规范

读时间槽参数

  • 主机低电平时间:>1μs

  • 采样窗口:低电平释放后 15μs 内

  • 位周期总时间:最小 60μs

五、驱动程序实现

5.1 硬件抽象层定义

复制代码
// 引脚操作宏定义
#define DS18B20_PORT  P3      // 使用P3端口
#define DS18B20_PIN   7       // 使用P3.7引脚

// 总线操作宏
#define DQ_LOW()     (DS18B20_PORT &= ~(1 << DS18B20_PIN))
#define DQ_HIGH()    (DS18B20_PORT |= (1 << DS18B20_PIN))
#define DQ_INPUT()   (DS18B20_PORT |= (1 << DS18B20_PIN))  // 设置为输入模式
#define DQ_READ()    ((DS18B20_PORT & (1 << DS18B20_PIN)) ? 1 : 0)

5.2 精确延时函数

复制代码
/**
 * @brief 微秒级延时函数
 * @param us 延时微秒数
 * @note 基于11.0592MHz晶振,12时钟周期
 */
void delay_us(unsigned int us)
{
    while(us--)
    {
        _nop_(); _nop_(); _nop_();
        _nop_(); _nop_(); _nop_();
        _nop_(); _nop_(); _nop_();
    }
}

/**
 * @brief 毫秒级延时函数
 * @param ms 延时毫秒数
 */
void delay_ms(unsigned int ms)
{
    while(ms--)
    {
        delay_us(1000);
    }
}

5.3 复位函数实现

复制代码
/**
 * @brief DS18B20复位序列
 * @return 1:复位成功,检测到器件存在
 *         0:复位失败,器件无响应
 */
uint8_t DS18B20_Reset(void)
{
    uint8_t presence = 0;
    
    // 主机驱动总线为低电平
    DQ_LOW();
    
    // 保持低电平480μs以上(推荐500-550μs)
    delay_us(550);
    
    // 主机释放总线,上拉电阻拉至高电平
    DQ_HIGH();
    DQ_INPUT();  // 切换为输入模式
    
    // 延时等待15-60μs
    delay_us(30);
    
    // 检测从机响应脉冲
    if(DQ_READ() == 0)
    {
        // 等待从机释放总线(60-240μs)
        uint16_t timeout = 250;
        while(!DQ_READ() && timeout--);
        
        if(timeout > 0)
        {
            presence = 1;  // 检测到器件
        }
    }
    
    // 等待总线恢复(至少480μs)
    delay_us(500);
    
    return presence;
}

5.4 数据读写函数

复制代码
/**
 * @brief 向DS18B20写入一个字节
 * @param data 要写入的数据字节
 */
void DS18B20_WriteByte(uint8_t data)
{
    uint8_t i;
    
    for(i = 0; i < 8; i++)
    {
        // 写时间槽开始
        DQ_LOW();
        
        if(data & 0x01)  // 写入"1"
        {
            // 保持低电平>1μs,然后释放总线
            _nop_(); _nop_();  // 约2μs延时
            DQ_HIGH();
            DQ_INPUT();
            
            // 保持总线高电平至少45μs
            delay_us(50);
        }
        else  // 写入"0"
        {
            // 保持低电平60-120μs
            delay_us(70);
            DQ_HIGH();
            DQ_INPUT();
        }
        
        // 写时间槽结束,恢复总线
        data >>= 1;  // 准备下一位
        delay_us(5); // 位间恢复时间
    }
    
    // 字节写入完成后,确保总线处于释放状态
    DQ_HIGH();
    DQ_INPUT();
}

/**
 * @brief 从DS18B20读取一个字节
 * @return 读取到的数据字节
 */
uint8_t DS18B20_ReadByte(void)
{
    uint8_t i;
    uint8_t data = 0;
    
    for(i = 0; i < 8; i++)
    {
        // 读时间槽开始
        DQ_LOW();
        _nop_(); _nop_();  // 约2μs低电平
        
        // 主机释放总线,准备采样
        DQ_HIGH();
        DQ_INPUT();
        
        // 延时15μs后采样
        delay_us(15);
        
        // 读取总线状态
        if(DQ_READ())
        {
            data |= (0x01 << i);  // 读取到"1"
        }
        
        // 完成读时间槽(总时间>60μs)
        delay_us(45);
        
        // 确保总线恢复
        DQ_HIGH();
        DQ_INPUT();
    }
    
    return data;
}

5.5 温度读取完整流程

复制代码
/**
 * @brief 读取当前温度值
 * @return 温度值(浮点数,单位:℃)
 * @note 使用12位分辨率,转换时间约750ms
 */
float DS18B20_ReadTemperature(void)
{
    uint8_t temp_low, temp_high;
    int16_t temp_raw;
    float temperature;
    
    // 步骤1:启动温度转换
    if(!DS18B20_Reset())
    {
        return ERROR_TEMPERATURE;  // 定义错误值,如-999.0
    }
    
    // 发送跳过ROM命令(仅单设备情况)
    DS18B20_WriteByte(0xCC);
    
    // 发送温度转换命令
    DS18B20_WriteByte(0x44);
    
    // 等待转换完成(12位分辨率需750ms)
    delay_ms(750);
    
    // 步骤2:读取温度数据
    if(!DS18B20_Reset())
    {
        return ERROR_TEMPERATURE;
    }
    
    // 发送跳过ROM命令
    DS18B20_WriteByte(0xCC);
    
    // 发送读暂存器命令
    DS18B20_WriteByte(0xBE);
    
    // 读取温度寄存器(低字节和高字节)
    temp_low = DS18B20_ReadByte();
    temp_high = DS18B20_ReadByte();
    
    // 合成16位温度原始值
    temp_raw = (temp_high << 8) | temp_low;
    
    // 步骤3:温度值转换
    // 判断温度符号
    if(temp_raw & 0x8000)  // 负温度
    {
        // 计算补码的绝对值
        temp_raw = ~temp_raw + 1;
        temperature = -(temp_raw * 0.0625);
    }
    else  // 正温度
    {
        temperature = temp_raw * 0.0625;
    }
    
    return temperature;
}

七、调试与故障排除

7.1 常见问题及解决方案

问题现象 可能原因 解决方案
读取温度始终为0 总线无上拉电阻 添加4.7kΩ上拉电阻至VCC
温度值异常波动 电源噪声干扰 在VDD和GND间添加100nF电容
器件无响应 时序不符合规范 使用逻辑分析仪检查时序
温度转换失败 延时不足 确保750ms转换等待时间
多个传感器冲突 ROM未正确匹配 实现ROM搜索和匹配算法

八、技术参数总结表

技术指标 规格描述
通信接口 单总线(1-Wire)
数据格式 16位二进制补码
转换精度 用户可编程9-12位
最大采样率 9位:约10.6Hz,12位:约1.33Hz
总线负载能力 理论上最多可挂接数百个器件
温度误差 ±0.5℃(-10℃至+85℃)
长期稳定性 ±0.2℃/年(典型值)
ESD保护 人体模型:≥4kV
相关推荐
武托邦2 小时前
关于海南骑行花费
学习
foundbug9992 小时前
基于STM32F103单片机实现汽车OBD诊断仪的开发方案
stm32·单片机·汽车
创作者mateo2 小时前
深度学习学习笔记:发展脉络以及核心原理全解析
笔记·深度学习·学习
江苏世纪龙科技2 小时前
虚实融合,技有所成——面向汽车专业的信息化综合实训考核平台
学习
行业探路者2 小时前
如何通过音频二维码生成提升信息分享效率?
大数据·人工智能·学习·二维码·产品介绍
一枝小雨2 小时前
【OTA专题】 20 上电立即跳转:加快MCU启动速度
stm32·单片机·嵌入式·ota·bootloader·加速启动
VekiSon2 小时前
51单片机——DS18B20 温度传感器
单片机·嵌入式硬件·51单片机
發糞塗牆2 小时前
Azure 架构师学习笔记 - Azure AI(1)- 概述
笔记·学习·ai·azure
CCPC不拿奖不改名2 小时前
大语言模型的基础:大语言模型基础认知
人工智能·python·学习·语言模型·自然语言处理·面向对象·智能体