代码改变世界

STM32驱动DS18B20温度传感器超详细教程 - 指南

2025-12-27 15:36  tlnshuju  阅读(0)  评论(0)    收藏  举报

一、DS18B20传感器简介与适用范围

1. 传感器简介
  • DS18B20是美国Dallas半导体公司推出的单总线数字温度传感器,采用独特的单总线协议,仅需一根信号线即可完成数据传输,无需额外模拟-to-数字转换器(ADC),直接输出数字温度值。其核心优势:

    - 测量范围广:-55℃~+125℃,满足绝大多数民用/工业场景需求;
    - 精度可调:默认0.0625℃(16位分辨率),可通过命令配置为0.5℃/0.25℃/0.125℃,兼顾精度与速度;
    - 供电灵活:支持3.3V~5V宽电压供电,可采用寄生电源(由DQ线供电)或外部电源供电;
    - 体积小巧:TO-92封装(类似三极管),便于焊接和嵌入狭小空间,且抗干扰能力强。
2. 适用范围
  • - 智能家居:室内温度监测、空调/加湿器联动控制、冰箱温度监控;
    - 工业控制:设备散热温度监测、车间环境温度采集、冷链运输温度追踪;
    - 医疗电子:体温计、 incubator(孵化器)温度检测、医疗设备环境温度监控;
    - 汽车电子:车内温度显示、发动机冷却系统温度监测;
    - 嵌入式学习:单片机入门必备项目,适合掌握单总线协议、时序控制等核心技能。

二、前期准备

1. 硬件清单
  • - 主控:STM32最小系统板
    - 传感器:DS18B20温度传感器(单总线数字传感器)
    - 辅助器材:4.7KΩ上拉电阻、杜邦线、5V/3.3V电源、USB-TTL下载器
    - 工具:Keil5(MDK-ARM)、STM32CubeMX(可选,快速初始化)、万用表(调试用)
2. 硬件接线说明(单总线核心)
  • DS18B20共3个引脚(VCC、GND、DQ),接线方式如下:

    DS18B20引脚 STM32C8T6引脚 备注 
    VCC 3.3V 严禁接5V,避免烧毁传感器 
    GND GND 共地,保证信号稳定 
    DQ PA1 单总线数据引脚(可自定义) 
    额外电路 4.7KΩ电阻 接在DQ引脚与3.3V之间(上拉,核心必备) 

    关键提醒:单总线必须加4.7KΩ上拉电阻,否则无法传输数据,这是新手最易踩的坑!

三、软件实现

1. 核心原理
  • DS18B20采用单总线协议,通过一根线完成复位-应答-命令-数据传输,核心步骤:

    1. 主机拉低DQ引脚≥480μs,发送复位信号;
    2. 释放DQ,等待DS18B20拉低DQ 60~240μs作为应答;
    3. 主机发送命令(如跳过ROM命令0xCC、温度转换命令0x44、读取数据命令0xBE);
    4. 读取16位温度数据,换算为实际温度值(高位×256 + 低位,精度0.0625℃)。
2. 部分代码(ds18b20.c)
/**
 * @brief       从ds18b20得到温度值(精度:0.1C)
 * @param       无
 * @retval      温度值 (-550~1250)
 *   @note      返回的温度值放大了10倍.
 *              实际使用的时候,要除以10才是实际温度.
 */
short ds18b20_get_temperature(void)
{
    uint8_t flag = 1;           /* 默认温度为正数 */
    uint8_t TL, TH;
    short temp;
    ds18b20_start();            /*  ds1820 start convert */
    //ds18b20_pin_in_or_out(0);
    delay_ms(30);
    //ds18b20_pin_in_or_out(1);
    ds18b20_reset();
    ds18b20_check();
    ds18b20_write_byte(0xcc);   /*  skip rom */
    ds18b20_write_byte(0xbe);   /*  convert */
    TL = ds18b20_read_byte();   /*  LSB */
    TH = ds18b20_read_byte();   /*  MSB */
    ds18b20_pin_in_or_out(1);
    if (TH > 7)
    {/* 温度为负,查看DS18B20的温度表示法与计算机存储正负数据的原理一致:
        正数补码为寄存器存储的数据自身,负数补码为寄存器存储值按位取反后+1
        所以我们直接取它实际的负数部分,但负数的补码为取反后加一,但考虑到低位可能+1后有进位和代码冗余,
        我们这里先暂时没有作+1的处理,这里需要留意 */
        TH = ~TH;
        TL = ~TL;
        flag = 0;   /* 温度为负 */
    }
    temp = TH;      /* 获得高八位 */
    temp <<= 8;
    temp += TL;     /* 获得底八位 */
    /* 转换成实际温度 */
    if (flag == 0)
    {   /* 将温度转换成负温度,这里的+1参考前面的说明 */
        temp = (double)(temp+1) * 0.625;
        temp = -temp;
    }
    else
    {
        temp = (double)temp * 0.625;
    }
    return temp;
}
3.头文件(ds18b20.h)
/**
 ****************************************************************************************************
 * @file        ds18b20.h
 * @author      送外卖的工程师
 * @version     V1.0
 * @date        2025-11-23
 * @brief       DS18B20数字温度传感器 驱动代码
 ****************************************************************************************************
 * @attention
 *
 * 实验平台:STM32F103C8T6
 *     CSDN:送外卖的工程师
 * 技术指导VX:wmz14026
 * 淘宝店铺:小马科技
 * 闲鱼店铺:送外卖的工程师
 *
 * 修改说明
 * V1.0.0.251123
 * 第一次发布
 * 注:长期接各种项目设计,提供仿真、实物、原理图、PCB、代码工程、后期指导、操作视频、
   说明文档、各种报告、后期指导等。
 ****************************************************************************************************
 */
#ifndef __DS18B20_H
#define __DS18B20_H
#include "main.h"
/******************************************************************************************/
/* DS18B20引脚 定义 */
#define DS18B20_DQ_GPIO_PORT                GPIOA
#define DS18B20_DQ_GPIO_PIN                 GPIO_PIN_1
#define DS18B20_DQ_GPIO_CLK_ENABLE()        do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)   /* PG口时钟使能 */
/******************************************************************************************/
/* IO操作函数 */
#define DS18B20_DQ_OUT(x)   do{ x ? \
                                HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_SET) : \
                                HAL_GPIO_WritePin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN, GPIO_PIN_RESET); \
                            }while(0)                                                       /* 数据端口输出 */
#define DS18B20_DQ_IN       HAL_GPIO_ReadPin(DS18B20_DQ_GPIO_PORT, DS18B20_DQ_GPIO_PIN)     /* 数据端口输入 */
uint8_t ds18b20_init(void);         /* 初始化DS18B20 */
uint8_t ds18b20_check(void);        /* 检测是否存在DS18B20 */
short ds18b20_get_temperature(void);/* 获取温度 */
#endif

四、调试与避坑指南

1. 常见问题排查

问题现象 可能原因 解决方案 
串口打印乱码/无温度值 传感器未检测到(DS18B20_Check返回1) 1. 检查接线(上拉电阻是否接对、DQ引脚是否松动);2. 传感器是否接反(VCC/GND接反会烧毁);3. 延时函数是否准确 
温度值固定为85℃ 初始化失败/转换未完成 1. 确认0x44转换命令发送后有足够延时;2. 检查复位-应答时序是否正确 
温度值误差大 电源不稳定/无屏蔽措施 1. 给传感器供电端加104电容滤波;2. 杜邦线尽量短(避免干扰) 
偶尔读取失败 单总线时序抖动 优化delay_us函数(用SysTick定时器实现精准延时) 

2. 关键优化技巧

- 延时精准性:单总线对时序要求极高,建议用SysTick定时器实现us级延时(避免软件延时误差);
- 多传感器扩展:若需连接多个DS18B20,需去掉0xCC(跳过ROM),改用0x55(匹配ROM)+ 传感器64位ROM地址;
- 低功耗优化:温度转换完成后,可将DQ引脚设为输入高电平,传感器进入低功耗模式(电流≤1μA)。

五、效果验证

1. 编译代码后下载到STM32F103C8T6;
2. OLED屏幕显示当前温度;
3. 触摸DS18B20传感器,温度会随之上升,松开触摸,会慢慢下降;验证成功。