DAY49 DS18B20 Single-Wire Digital Temperature Acquisition

DS18B20 Single-Wire Digital Temperature Acquisition

I. DS18B20 Core Features & Hardware Basics

1. Key Parameters (Must Remember!)

Parameter Specifications
Measurement Range -55℃ ~ +125℃ (Full industrial coverage)
Accuracy ±0.5℃ within -10℃~+85℃, ≤±2℃ full range
Resolution Adjustable 9~12 bits (default 12-bit): 9-bit=0.5℃, 10-bit=0.25℃, 11-bit=0.125℃, 12-bit=0.0625℃
Operating Voltage 3V~5.5V (Compatible with 51 MCU 3.3V/5V power, no extra regulator needed)
Communication Interface Single-wire GPIO bus (Only 1 I/O pin + GND, extremely low hardware cost)
Core Advantages No external components, strong anti-interference, supports multi-sensor networking, retains configuration during power loss

2. Pin Definitions & Wiring

DS18B20 uses TO-92 package with 3 pins. 51 MCU wiring:

DS18B20 Pin Function 51 MCU Connection
VDD Power pin Connect to 3.3V/5V (external power mode) or leave floating (parasitic power mode)
DQ Data I/O Connect to any GPIO (code uses P3.7) + 4.7KΩ pull-up resistor
GND Ground Connect to MCU GND (must share ground to prevent signal interference)

Critical Note: Single-wire bus must have 4.7KΩ pull-up resistor to ensure high level when idle for stable communication.


II. DS18B20 Core Timing Principles (Communication Key!)

DS18B20 communication relies on strict timing protocols. All operations (reset, write, read) must follow single-wire bus timing rules - the core of successful acquisition.

1. Reset Timing (Initialization)

All communication starts with reset:

  1. Host (51 MCU) pulls bus low ≥480μs (reset pulse);
  2. Host releases bus, switches to input mode after pulling high;
  3. DS18B20 detects rising edge, delays 15~60μs, then pulls bus low 60~240μs (presence pulse) to signal "ready";
  4. DS18B20 releases bus, returns to high level, enters idle state.

Code implementation: ds18b20_reset() uses Delay10us(70) for 700μs reset, Delay10us(6) to wait for presence pulse.

2. Write Timing (Host→DS18B20)

Host sends "0" or "1" via different low-level durations (LSB first, 8 bits = 1 byte):

  • Write 0 : Pull bus low ≥60μs → release (pull high); DS18B20 samples within 60μs, low level = "0";
  • Write 1 : Pull bus low 1~15μs → release (pull high); DS18B20 samples high level = "1";
  • Minimum 1μs recovery between writes.

Code implementation: write_ds18b20() uses dat&1 to determine bit, short delay for 1, long delay for 0.

3. Read Timing (DS18B20→Host)

Host triggers read by pulling bus low, then DS18B20 controls bus level:

  1. Host pulls bus low ≥1μs → immediately releases (pull high);
  2. Host samples bus level within 15μs (high=1, low=0);
  3. Single read duration ≥60μs, minimum 1μs between reads.

Code implementation: read_ds18b20() pulls low then quickly releases, detects level via DQ_CHECK, stores in dat.


III. Core Command Analysis (DS18B20 Operation Soul)

DS18B20 executes operations based on 8-bit host commands. Code uses 3 core commands:

Command Byte Command Name Function
0xCC Skip ROM Bypasses reading DS18B20's 64-bit ROM code (preferred for single-sensor scenarios)
0x44 Convert T Initiates temperature conversion (12-bit takes ~750ms), bus must stay high during conversion
0xBE Read Scratchpad Reads DS18B20's 9-byte scratchpad (first 2 bytes contain temperature data)

Extension: Multi-sensor networks require 0x55 (Match ROM) + 64-bit ROM code to target specific sensors.


IV. Complete 51 MCU Code Analysis

Code implements "Reset → Measure → Read → Data Processing" via P3.7 pin, ready for compilation.

1. Header & Macros (ds18b20.h)

c 复制代码
#ifndef __DS18B20_H__
#define __DS18B20_H__

#include <reg51.h>

// Function declarations
int ds18b20_reset(void);          // Reset DS18B20
void write_ds18b20(unsigned char dat); // Write 1 byte to DS18B20
unsigned char read_ds18b20(void);    // Read 1 byte from DS18B20
float get_temp(void);               // Get temperature (returns float)

#endif

2. Core Function Implementation (ds18b20.c)

c 复制代码
#include <reg51.h>
#include <intrins.h>
#include "ds18b20.h"
#include "delay.h"

// Macro definitions: P3.7 as DQ pin
#define  DQ_DOWN  (P3 &= ~(1 << 7))  // Pull DQ low
#define  DQ_HIGH  (P3 |= (1 << 7))  // Pull DQ high
#define  DQ_CHECK ((P3 & (1 << 7)) != 0)  // Check DQ level

/**
 * @brief  DS18B20 reset initialization
 * @retval 1-Reset successful, 0-Reset failed
 */
int ds18b20_reset(void)
{
    int t = 0;

    // 1. Send reset pulse (pull low ≥480μs)
    DQ_DOWN;
    Delay10us(70);  // 70×10μs=700μs, meeting ≥480μs requirement
    DQ_HIGH;         // Release the bus
    Delay10us(6);    // Wait 60μs to receive presence pulse

    // 2. Detect presence pulse (DS18B20 pulls bus low)
    while (DQ_CHECK && t < 30)  // Timeout 300μs if no low level detected → failure
    {
        Delay10us(1);
        t++;
    }
    if (t >= 30) return 0;  // Reset failed

    // 3. Wait for presence pulse to end (DS18B20 pulls bus high)
    t = 0;
    while (!DQ_CHECK && t < 30)  // Timeout 300μs if not pulled high → failure
    {
        Delay10us(1);
        t++;
    }
    if (t >= 30) return 0;  // Reset failed

    return 1;  // Reset successful
}

/**
 * @brief  Write 1 byte to DS18B20 (LSB first)
 * @param  dat: Byte to send
 */
void write_ds18b20(unsigned char dat)
{
    int i = 0;

    for (i = 0; i < 8; i++)  // Loop 8 times, writing 1 bit each time
    {
        if (dat & 1)  // Write 1: Pull low for 1~15μs
        {
            DQ_DOWN;
            _nop_();  // Short delay (~1μs)
            _nop_();
            DQ_HIGH;  // Release the bus
            Delay10us(5);  // Wait 45μs to ensure DS18B20 sampling
        }
        else  // Write 0: Pull low ≥60μs
        {
            DQ_DOWN;
            Delay10us(6);  // 60μs
            DQ_HIGH;      // Release the bus
        }
        dat >>= 1;  // Right shift 1 bit, preparing to write next bit (LSB first)
    }
}

/**
 * @brief  Read 1 byte from DS18B20 (LSB first)
 * @retval Byte read
 */
unsigned char read_ds18b20(void)
{
    unsigned char dat = 0;
    int i = 0;

    for (i = 0; i < 8; i++)  // Loop 8 times, reading 1 bit each time
    {
        DQ_DOWN;  // Pull low ≥1μs to trigger read operation
        _nop_();
        _nop_();
        DQ_HIGH;   // Release the bus, letting DS18B20 control the level
        _nop_();
        _nop_();
        _nop_();    // Delay ~3μs, preparing to sample

        if (DQ_CHECK)  // Sample level: high=1, low=0
        {
            dat |= (1 << i);  // Store corresponding bit (LSB first)
        }
        Delay10us(6);  // Single read operation ≥60μs
    }

    return dat;
}

/**
 * @brief  Get temperature value
 * @retval Float temperature (precision 0.0625℃)
 */
float get_temp(void)
{
    unsigned char tl = 0;  // Temperature low byte (LSB)
    unsigned char th = 0;  // Temperature high byte (MSB, including sign bit)
    short t = 0;           // Combined 16-bit temperature data

    // 1. Reset→Skip ROM→Start temperature conversion
    if (ds18b20_reset() == 0) return -99.9;  // Return error value if reset fails
    write_ds18b20(0xCC);  // Skip ROM (single sensor)
    write_ds18b20(0x44);  // Start temperature conversion
    Delay1ms(1000);       // Wait for conversion to complete (≥750ms for 12-bit resolution)

    // 2. Reset→Skip ROM→Read scratchpad
    ds18b20_reset();
    write_ds18b20(0xCC);  // Skip ROM
    write_ds18b20(0xBE);  // Read scratchpad

    // 3. Read temperature data (first 2 bytes are temperature value, LSB first)
    tl = read_ds18b20();  // Low byte
    th = read_ds18b20();  // High byte

    // 4. Combine temperature data (16-bit signed two's complement)
    t = th << 8;  // High byte left shift 8 bits
    t |= tl;      // Combine low byte

    // 5. Temperature conversion: 12-bit resolution→1LSB=0.0625℃
    return t * 0.0625;
}

3. Delay Function Support (delay.c/h)

DS18B20 timing requires high-precision delays (10μs, 1ms level with 11.0592MHz crystal):

c 复制代码
// delay.h
#ifndef __DELAY_H__
#define __DELAY_H__
void Delay10us(unsigned int n);
void Delay1ms(unsigned int n);
#endif

// delay.c
#include <reg51.h>
void Delay10us(unsigned int n)
{
    unsigned int i, j;
    for (i = n; i > 0; i--)
        for (j = 2; j > 0; j--);  // ≈10μs at 11.0592MHz
}

void Delay1ms(unsigned int n)
{
    unsigned int i, j;
    for (i = n; i > 0; i--)
        for (j = 110; j > 0; j--);  // ≈1ms at 11.0592MHz
}

4. Main Function Call Example (main.c)

c 复制代码
#include <reg51.h>
#include "ds18b20.h"
#include "uart.h"  // Assuming UART send functions are implemented

void main(void)
{
    float temp;
    uart_init();  // Initialize UART (for printing temperature)

    while (1)
    {
        temp = get_temp();  // Get temperature
        if (temp != -99.9)  // Successful acquisition
        {
            // UART print temperature (floating-point to string function omitted here)
            uart_sendstr("Current temperature: ");
            // Example: Print integer part + decimal part
        }
        Delay1ms(2000);  // Sample every 2 seconds
    }
}

5. Key Practical Considerations

  1. Pull-up resistor is essential: A 4.7KΩ pull-up resistor is critical for stable single-wire bus communication; its absence can cause reset failures or data errors.
  2. Delay precision must meet requirements: Timing parameters (e.g., 480μs reset, 60μs write 0) must strictly match; excessive delay errors will cause acquisition failures.
  3. Wait for temperature conversion: After issuing the conversion command (0x44), sufficient time must be allowed (≥750ms for 12-bit resolution); otherwise, old data will be read.
  4. Parasitic power mode note: If DS18B20 uses parasitic power (VDD floating), the bus must remain high during conversion, and no other operations should be performed.
  5. Multi-sensor networking : Use 0x55 (Match ROM) command + sensor's unique 64-bit ROM code to avoid data conflicts.

6. Temperature Data Parsing Principle

DS18B20 stores temperature data as 16-bit signed two's complement:

Bit 15 (MSB) Bits 14-11 Bits 10-4 Bits 3-0 (LSB)
Sign bit (0=positive, 1=negative) Integer part Fractional part Fractional part (12-bit resolution)
  • Positive numbers: Directly convert using "integer part × 1 + fractional part × 0.0625".
  • Negative numbers: Convert using two's complement rules (invert + 1) before calculation, with negative sign.
  • Example: 25.5℃ → Binary 00000000 00011001.1000 → Hex 0x00198 → Convert to 25 + 8×0.0625=25.5℃.

Summary

DS18B20's core advantages are "single-wire communication + minimal hardware". Key learning focuses on timing protocol and command parsing: Reset is the communication prerequisite, write/read timing forms the data transmission foundation, and temperature conversion/scratchpad read commands are core operations. Mastering the code and principles here enables easy expansion to multi-sensor networks, temperature alarms (using TH/TL registers), UART temperature uploads, etc., making it suitable for embedded applications like environmental monitoring and equipment temperature control.

相关推荐
未济3 天前
linux 配置环境变量
linux
傲世仙尊3 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
_艾伦 耶格尔.3 天前
进程间通信
linux
Liuqy-053 天前
Linux IO编程——静态库、动态库
linux
wuyk5553 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网