欢迎光临
我们一直在努力

DS18B20 数字温度传感器

一、传感器概述

DS18B20 是一款数字温度传感器,通过单总线(One-Wire)与单片机通信,只需一根 GPIO 信号线即可完成数据传输。

二、传感器指标参数

参数说明
量程(温度测量范围) -55℃ 至 125℃
精度(最大允许误差) ±0.5℃
工作电压 3V – 5.5V

精度说明:精度指传感器测量的温度与实际温度值之间允许的最大误差。例如实际温度为 25℃ 时,传感器采集温度值在 24.5℃ – 25.5℃ 之间。

三、分辨率

分辨率反映传感器对温度变化的敏感程度。分辨率越高,能察觉到的微小温度变化越小,读数越细腻。

位数分辨率
9 位 0.5℃
10 位 0.25℃
11 位 0.125℃
12 位 0.0625℃

四、51 单片机与 DS18B20 通信

通信方式为半双工、异步、串行通信。DS18B20 通过一根 GPIO 信号线(DQ)与单片机连接,采用 One-Wire 单总线协议。

51 单片机DS18B20
VCC 电源
DQ 数据线
GND 地线

线与特性

单总线具有线与特性,引脚拉高时不能直接决定引脚电平,拉高表示释放总线。当作为数据接收方时,需要释放总线。

51 引脚DS18B20总线电平
1 0 0
0 1 0
1 1 1
0 0 0

GPIO 输出模式用于发送数据,GPIO 输入模式用于接收数据。读数格式为 16 位、符号位扩展、二进制补码。

五、DS18B20 采集温度流程

六、时序详解

1. 复位时序

  • 主机将总线拉低 480us – 960us,发送复位脉冲
  • 主机释放总线,需要延时 15us – 60us
  • DS18B20 将总线拉低 60us – 240us,回复响应脉冲
  • DS18B20 释放总线,总线呈现高电平,初始化过程结束
  • 对应函数:ds18b20_reset();

    // ds18b20 复位

    int ds18b20_reset(void)

    {

    int time = 0;

    // 主机向ds18b20发送复位脉冲

    DQ_PIN_LOW;

    Delay10us(70);

    DQ_PIN_HIGH;

    Delay10us(6);

    // 等待低电平到来 (超时时间)

    while (DQ_CHECK && time < 30)

    {

    Delay10us(1);

    time++;

    }

    if (time >= 30)

    {

    uart_sendstr("wait ds18b20_low timeout!\\n");

    return -1;

    }

    // 等待高电平到来

    time = 0;

    while (!DQ_CHECK && time < 30)

    {

    Delay10us(1);

    time++;

    }

    if (time >= 30)

    {

    uart_sendstr("wait ds18b20_high timeout!\\n");

    return -2;

    }

    return 1;

    }

    2. 写时序

    写 '0' 时序:

  • 主机将总线拉低至少 60us,最多不超过 120us
  • DS18B20 在 15us – 60us 内进行采样,若总线此时为低电平,则代表主机发送了 '0'
  • 主机释放总线
  • 写 '1' 时序:

  • 主机将总线拉低小于 15us,释放总线
  • DS18B20 在 15us – 60us 内进行采样,若总线此时为高电平,则代表主机发送了 '1'
  • // 主机发送一个字节

    void write_ds18b20(unsigned char dat)

    {

    int i = 0;

    for (i = 0; i < 8; i++)

    {

    if (dat & 1) // 写1

    {

    DQ_PIN_LOW;

    _nop_();

    _nop_();

    DQ_PIN_HIGH;

    Delay10us(6);

    }

    else // 写0

    {

    DQ_PIN_LOW;

    Delay10us(6);

    DQ_PIN_HIGH;

    }

    dat >>= 1;

    }

    }

    3. 读时序

    读 '1' 时序:

  • 主机拉低总线,大于 1us,然后释放总线
  • DS18B20 释放总线,总线呈现高电平
  • 主机在 15us 内采样电平,此时总线为高电平,代表主机读到 '1'
  • 读 '0' 时序:

  • 主机拉低总线,大于 1us,然后释放总线
  • DS18B20 在主机释放总线后,主动拉低(代表要传输 '0')
  • 主机在 15us 内进行采样,此时总线为低电平,代表主机读到 '0'
  • // 主机读取一个字节

    unsigned char read_ds18b20(void)

    {

    unsigned char dat = 0;

    int i = 0;

    for (i = 0; i < 8; i++)

    {

    DQ_PIN_LOW;

    _nop_();

    _nop_();

    DQ_PIN_HIGH;

    _nop_();

    _nop_();

    _nop_();

    // 代表读到1

    if (DQ_CHECK)

    {

    dat |= (1 << i);

    }

    Delay10us(6);

    }

    return dat;

    }

    七、关键指令与代码

    指令说明:

    • 0xCC(1100 1100):跳过 ROM 指令
    • 0x44:开启温度转换指令
    • 0xBE:读取温度指令

    写数据函数:

    void write_ds18b20(unsigned char dat)
    {
    // 按位写入,每位遵循写时序要求
    }

    典型调用:

    // 读取ds18b20温度
    float get_temp(void)
    {
    unsigned char temp_low = 0;
    unsigned char temp_high = 0;
    short temp = 0;

    ds18b20_reset(); // 复位
    write_ds18b20(0xCC); // skip ROM
    write_ds18b20(0x44); // 开启温度转换
    Delay1ms(1000); // 等待温度转换完毕
    ds18b20_reset(); // 复位
    write_ds18b20(0xCC); // skip ROM
    write_ds18b20(0xBE); // 读取温度

    temp_low = read_ds18b20(); // 读取温度低位
    temp_high = read_ds18b20(); // 读取温度高位

    // 2个字节温度值
    temp = temp_high << 8;
    temp |= temp_low;

    return temp * 0.0625;
    }

    赞(0)
    未经允许不得转载:171主机测评 » DS18B20 数字温度传感器
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址