news 2026/4/14 21:38:35

简单理解:DS18B20 驱动的宏定义(部分)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单理解:DS18B20 驱动的宏定义(部分)
// 宏定义 #define DS18B20_IO_OUT() GPIO_DirectionConfig(DS18B20_PORT, DS18B20_PIN, GPIO_DIR_OUT) #define DS18B20_IO_IN() GPIO_DirectionConfig(DS18B20_PORT, DS18B20_PIN, GPIO_DIR_IN) #define DS18B20_DQ_OUT GPIO_ClearOutBits(DS18B20_PORT, DS18B20_PIN) #define DS18B20_DQ_OUT_1 GPIO_SetOutBits(DS18B20_PORT, DS18B20_PIN) #define DS18B20_DQ_IN GPIO_ReadInBit(DS18B20_PORT, DS18B20_PIN)

逐行解释这段单片机(STM32 / 国产 MCU 通用)DS18B20 驱动的宏定义,讲清楚每个宏是干嘛的、怎么用。

整体作用

这是DS18B20 温度传感器单总线(1-Wire)驱动里最常见的 GPIO 操作封装,用宏把引脚方向、输出高低、读取电平藏起来,让主代码更干净、易移植。

逐行解释

1. 设置引脚为输出模式

#define DS18B20_IO_OUT() GPIO_DirectionConfig(DS18B20_PORT, DS18B20_PIN, GPIO_DIR_OUT)
  • 功能:把 DS18B20 的 DQ 引脚设为推挽输出
  • 使用:DS18B20_IO_OUT();

2. 设置引脚为输入模式

#define DS18B20_IO_IN() GPIO_DirectionConfig(DS18B20_PORT, DS18B20_PIN, GPIO_DIR_IN)
  • 功能:把 DQ 引脚设为输入(上拉 / 浮空)
  • 使用:DS18B20_IO_IN();

3. 输出低电平(拉低 DQ)

#define DS18B20_DQ_OUT GPIO_ClearOutBits(DS18B20_PORT, DS18B20_PIN)
  • 功能:DQ =0
  • 使用:DS18B20_DQ_OUT;

4. 输出高电平(拉高 DQ)

#define DS18B20_DQ_OUT_1 GPIO_SetOutBits(DS18B20_PORT, DS18B20_PIN)
  • 功能:DQ =1
  • 使用:DS18B20_DQ_OUT_1;

5. 读取引脚电平

#define DS18B20_DQ_IN GPIO_ReadInBit(DS18B20_PORT, DS18B20_PIN)
  • 功能:读取当前 DQ 是高还是低
  • 返回值:01
  • 使用:level = DS18B20_DQ_IN;

典型使用片段(你能直接对照)

// 复位时序示例 DS18B20_IO_OUT(); // 设置DS18B20的DQ引脚为输出模式(准备发送复位脉冲) DS18B20_DQ_OUT = 0; // 将DQ引脚拉低(发送复位脉冲,协议要求低电平至少480us,这里用1ms满足要求) delay_ms(1); // 保持拉低状态1ms(远大于协议最小480us要求,确保DS18B20能检测到复位) DS18B20_DQ_OUT = 1; // 释放总线(拉高DQ引脚,结束复位脉冲) delay_us(40); // 等待40us(协议要求主机释放总线后,等待15~60us检测从机应答) DS18B20_IO_IN(); // 将DQ引脚切换为输入模式(释放总线,准备检测DS18B20的应答脉冲) if(DS18B20_DQ_IN == 0) // 检测DQ引脚电平:若为低,说明DS18B20发送了应答脉冲 { // 存在应答 }

// DS18B20状态机状态枚举 typedef enum { DS18B20_STATE_IDLE = 0, // 空闲状态 DS18B20_STATE_RESET_START, // 开始复位 DS18B20_STATE_RESET_WAIT, // 等待复位完成 DS18B20_STATE_CHECK_PRESENCE, // 检查存在脉冲 DS18B20_STATE_SEND_SKIP_ROM, // 发送跳过ROM命令 DS18B20_STATE_SEND_CONVERT, // 发送温度转换命令 DS18B20_STATE_CONVERT_WAIT, // 等待转换完成 DS18B20_STATE_READ_SCRATCHPAD, // 发送读取暂存器命令 DS18B20_STATE_READ_TEMP_LSB, // 读取温度低8位 DS18B20_STATE_READ_TEMP_MSB, // 读取温度高8位 DS18B20_STATE_COMPLETE, // 温度读取完成 DS18B20_STATE_ERROR // 错误状态 } DS18B20_State; // DS18B20状态机结构体 typedef struct { DS18B20_State state; // 当前状态 uint32_t timestamp; // 时间戳 short temperature; // 温度值 uint8_t temp_lsb; // 温度低8位 uint8_t temp_msb; // 温度高8位 uint8_t error; // 错误标志 } DS18B20_HandleTypeDef;

这段代码是针对 DS18B20 温度传感器设计的状态机相关定义,核心目的是通过枚举和结构体来规范化、模块化地管理 DS18B20 的工作流程和状态数据。下面我会详细拆解每一部分的含义和作用。

1. DS18B20 状态机状态枚举(DS18B20_State)

这个枚举定义了 DS18B20 传感器从空闲到完成温度读取的完整工作流程中的所有状态,每个状态对应传感器操作的一个具体步骤,是状态机的核心 “状态标识”。

枚举值中文含义作用说明
DS18B20_STATE_IDLE空闲状态传感器初始状态,未执行任何操作,等待触发读取流程
DS18B20_STATE_RESET_START开始复位触发 DS18B20 的复位操作(1-Wire 总线复位)
DS18B20_STATE_RESET_WAIT等待复位完成等待复位时序完成(DS18B20 复位需要固定的时序等待)
DS18B20_STATE_CHECK_PRESENCE检查存在脉冲检测 DS18B20 是否返回存在脉冲(确认传感器在线)
DS18B20_STATE_SEND_SKIP_ROM发送跳过 ROM 命令发送 0xCC 命令(跳过 ROM 匹配,适用于单传感器场景)
DS18B20_STATE_SEND_CONVERT发送温度转换命令发送 0x44 命令(触发传感器进行温度转换)
DS18B20_STATE_CONVERT_WAIT等待转换完成等待温度转换结束(转换需要约 750ms,可通过时序或延时等待)
DS18B20_STATE_READ_SCRATCHPAD发送读取暂存器命令发送 0xBE 命令(读取传感器的暂存器数据)
DS18B20_STATE_READ_TEMP_LSB读取温度低 8 位读取暂存器中温度值的低 8 位数据
DS18B20_STATE_READ_TEMP_MSB读取温度高 8 位读取暂存器中温度值的高 8 位数据
DS18B20_STATE_COMPLETE温度读取完成温度值解析完成,状态机结束流程
DS18B20_STATE_ERROR错误状态任意步骤出错(如无存在脉冲、读取数据异常)时进入此状态

2. DS18B20 状态机结构体(DS18B20_HandleTypeDef)

这个结构体是管理单个 DS18B20 传感器的 “数据容器”,整合了状态机的状态、时间戳、温度数据和错误信息,方便在程序中统一管理。

成员变量类型作用说明
stateDS18B20_State记录传感器当前所处的状态(对应上面的枚举值),是状态机的核心变量
timestampuint32_t时间戳(通常记录进入当前状态的系统时间),用于时序等待(如复位等待、转换等待时判断是否超时)
temperatureshort最终解析后的温度值(DS18B20 的温度是 16 位有符号数,short 刚好适配,单位通常是 0.0625℃,需换算)
temp_lsbuint8_t暂存读取到的温度低 8 位数据(未解析的原始数据)
temp_msbuint8_t暂存读取到的温度高 8 位数据(未解析的原始数据)
erroruint8_t错误标志(如 0 表示无错,非 0 表示对应错误类型,比如 1 = 复位失败、2 = 无存在脉冲等)

3. 实际使用逻辑示例(帮助理解)

状态机的执行流程通常是 “状态切换 + 时序判断”,比如:

// 初始化状态机 DS18B20_HandleTypeDef ds18b20 = { .state = DS18B20_STATE_IDLE, .timestamp = 0, .temperature = 0, .temp_lsb = 0, .temp_msb = 0, .error = 0 }; // 状态机处理函数(通常在定时器中断或主循环中调用) void DS18B20_StateMachine(DS18B20_HandleTypeDef *hdts) { switch(hdts->state) { case DS18B20_STATE_IDLE: // 触发读取,切换到复位开始状态 hdts->state = DS18B20_STATE_RESET_START; break; case DS18B20_STATE_RESET_START: // 执行复位操作(拉低总线) DS18B20_Reset(); hdts->timestamp = HAL_GetTick(); // 记录进入此状态的时间 hdts->state = DS18B20_STATE_RESET_WAIT; break; case DS18B20_STATE_RESET_WAIT: // 判断是否等待足够时间(如480us) if(HAL_GetTick() - hdts->timestamp > 1) { // 示例:简化的延时判断 hdts->state = DS18B20_STATE_CHECK_PRESENCE; } break; // 其他状态的处理逻辑... case DS18B20_STATE_ERROR: // 错误处理,比如重置状态机 hdts->state = DS18B20_STATE_IDLE; hdts->error = 0; break; } }

总结

  1. 枚举DS18B20_State把 DS18B20 的读取流程拆分成多个独立状态,符合 “状态机” 设计思想,便于分步处理和故障定位;
  2. 结构体DS18B20_HandleTypeDef整合了状态、时间、数据、错误信息,是管理单个传感器的核心数据结构;
  3. 这种设计适用于嵌入式系统(如 STM32),能避免阻塞式延时,提高程序的实时性和可靠性。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 19:43:03

OpenGL ES ->图片纹理不变形显示:两层宽高比校正详解

OpenGL ES 图片纹理不变形显示:两层宽高比校正详解 在 OpenGL ES 中把一张图片正确显示到屏幕上,需要解决两个完全不同的宽高比问题。本文用一个完整的数值示例,从顶点定义到最终像素,讲清楚每一步为什么必须这样做。一、核心矛盾…

作者头像 李华
网站建设 2026/4/11 0:12:04

小红的二叉树【牛客tracker 每日一题】

小红的二叉树 时间限制:1秒 空间限制:1024M 知识点:数论 网页链接 牛客tracker 牛客tracker & 每日一题,完成每日打卡,即可获得牛币。获得相应数量的牛币,能在【牛币兑换中心】,换取相…

作者头像 李华
网站建设 2026/4/10 23:42:24

苹果应用隐私政策配置指南

引言 在开发iOS应用的过程中,隐私政策的配置是一个不可忽视的重要环节。苹果公司对应用的隐私保护有着严格的要求,如果不正确配置隐私信息,可能会导致应用无法通过审核。本文将详细介绍如何配置苹果应用的隐私政策,并通过一个实际案例来展示解决常见问题的步骤。 理解隐私…

作者头像 李华
网站建设 2026/4/11 20:32:57

多线程Web爬虫:如何避免超时错误

在解决LeetCode的多线程Web爬虫问题时,我发现一个有趣的现象:使用ThreadPoolExecutor时,代码可能会超时,即使是在非常简单的测试用例中。今天,我们来探讨一下为什么会发生这种情况,并提供一个优化方案。 问题分析 首先,让我们回顾一下原始的代码实现: class Solutio…

作者头像 李华
网站建设 2026/4/12 7:56:50

大数据环境下 Kafka 的集群搭建指南

大数据环境下 Kafka 的集群搭建指南 关键词:Kafka 集群、大数据、分布式系统、消息队列、高吞吐量 摘要:在大数据时代,如何高效处理海量实时数据流是企业的核心需求之一。Kafka 作为一款分布式消息队列,凭借高吞吐量、低延迟和强容…

作者头像 李华
网站建设 2026/4/12 12:48:03

智能配电监控模块:50A磁保持,负载5500W电机设备,工业配电安全新方案

智能配电监控模块是一款集大功率远程控制、每路独立电流监控和多功能自动化逻辑于一体的先进电气管理终端设备。一、核心特性 50A磁保持:指其核心执行单元。 能力:每路通道能安全承载和控制高达50安培的大电流,可直接驱动电机、电热器等11KW级…

作者头像 李华