news 2026/4/18 17:30:35

STM32CubeIDE实战:用HAL库搞定DS18B20和DHT11温湿度采集(附完整工程)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32CubeIDE实战:用HAL库搞定DS18B20和DHT11温湿度采集(附完整工程)

STM32CubeIDE实战:HAL库驱动DS18B20与DHT11的工程化实现

在嵌入式开发领域,环境监测系统的快速原型开发一直是工程师面临的挑战。传统开发方式需要手动配置寄存器、编写底层驱动,而现代STM32CubeIDE配合HAL库的出现,让开发者能够更专注于业务逻辑的实现。本文将带你从零构建一个工业级精度的温湿度监测系统,使用单总线技术同时集成DS18B20高精度温度传感器和DHT11温湿度复合传感器。

1. 环境搭建与CubeMX配置

1.1 工程创建与时钟配置

打开STM32CubeIDE,选择对应型号的STM32微控制器(如STM32F103C8T6)。在RCC配置中启用外部高速时钟(HSE),将主时钟设置为72MHz。对于单总线设备,精确的时序控制至关重要,因此需要确保系统时钟配置正确。

关键配置步骤:

  • 在Pinout视图找到合适的GPIO引脚(如PA0)
  • 设置GPIO模式为"GPIO_Output"
  • 在Configuration标签页配置GPIO参数:
    GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

1.2 单总线协议基础

DS18B20和DHT11都采用单总线通信协议,但时序要求有所不同:

特性DS18B20DHT11
通信速率15μs-60μs脉冲20μs-200μs脉冲
数据格式16位温度数据40位温湿度数据
供电方式寄生电源或3-5V3-5V供电
精度±0.5°C(9-12位可调)±2°C/±5%RH

2. DS18B20高精度温度采集

2.1 硬件连接与初始化

DS18B20典型接线方式为VDD(3.3V)、DQ(信号线)、GND三线制。在CubeMX中配置好GPIO后,需要实现精确的微秒级延时函数:

void delay_us(uint16_t us) { uint16_t delay = (us * (SystemCoreClock / 1000000)) / 5; while(delay--); }

2.2 单总线通信实现

DS18B20的通信包含复位、写时序和读时序三个关键部分。以下是复位信号的HAL库实现:

uint8_t DS18B20_Reset(void) { uint8_t presence = 0; HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_RESET); delay_us(480); HAL_GPIO_WritePin(DS18B20_GPIO_Port, DS18B20_Pin, GPIO_PIN_SET); delay_us(60); presence = !HAL_GPIO_ReadPin(DS18B20_GPIO_Port, DS18B20_Pin); delay_us(420); return presence; }

2.3 温度数据读取与处理

完整的温度采集流程包括发送转换命令和读取暂存器:

float DS18B20_ReadTemp(void) { uint8_t tempL, tempH; uint16_t temp; DS18B20_Reset(); DS18B20_WriteByte(0xCC); // Skip ROM DS18B20_WriteByte(0x44); // Convert T HAL_Delay(750); // 等待转换完成 DS18B20_Reset(); DS18B20_WriteByte(0xCC); // Skip ROM DS18B20_WriteByte(0xBE); // Read Scratchpad tempL = DS18B20_ReadByte(); tempH = DS18B20_ReadByte(); temp = (tempH << 8) | tempL; return temp * 0.0625f; // 12位分辨率转换 }

3. DHT11温湿度采集实战

3.1 通信时序实现

DHT11采用严格的时序协议,起始信号需要保持至少18ms的低电平:

void DHT11_Start(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; // 配置为输出模式 GPIO_InitStruct.Pin = DHT11_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct); // 发送起始信号 HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_RESET); HAL_Delay(18); HAL_GPIO_WritePin(DHT11_GPIO_Port, DHT11_Pin, GPIO_PIN_SET); delay_us(30); // 切换为输入模式 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(DHT11_GPIO_Port, &GPIO_InitStruct); }

3.2 数据位解析技巧

DHT11的每位数据通过不同长度的高电平来区分0和1:

uint8_t DHT11_ReadBit(void) { while(!HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)); // 等待低电平结束 delay_us(40); uint8_t bit = HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin); while(HAL_GPIO_ReadPin(DHT11_GPIO_Port, DHT11_Pin)); // 等待高电平结束 return bit; }

3.3 数据校验与处理

完整的温湿度读取函数需要处理5字节数据并进行校验:

uint8_t DHT11_ReadData(uint8_t *humidity, uint8_t *temperature) { uint8_t data[5] = {0}; DHT11_Start(); // 等待DHT11响应 if(!DHT11_WaitResponse()) return 0; // 读取40位数据 for(int i=0; i<5; i++) { for(int j=0; j<8; j++) { data[i] <<= 1; data[i] |= DHT11_ReadBit(); } } // 校验和验证 if(data[4] == (data[0] + data[1] + data[2] + data[3])) { *humidity = data[0]; *temperature = data[2]; return 1; } return 0; }

4. 工程优化与高级应用

4.1 多设备总线管理

当系统中需要连接多个DS18B20时,可以通过ROM匹配命令实现设备寻址:

void DS18B20_MatchROM(uint8_t *rom) { DS18B20_WriteByte(0x55); // Match ROM命令 for(int i=0; i<8; i++) { DS18B20_WriteByte(rom[i]); } }

4.2 抗干扰设计

工业环境中单总线容易受到干扰,可采取以下措施:

  • 在信号线添加4.7kΩ上拉电阻
  • 使用屏蔽线缆
  • 实现软件CRC校验
  • 增加重试机制

4.3 低功耗优化

对于电池供电设备,可优化为间歇采样模式:

void Enter_StopMode(void) { // 配置唤醒引脚 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); // 进入停止模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 唤醒后重新配置时钟 SystemClock_Config(); }

5. 完整工程架构设计

5.1 模块化文件结构

建议采用以下工程结构:

├── Core │ ├── Src │ │ ├── main.c │ │ ├── ds18b20.c │ │ └── dht11.c │ └── Inc │ ├── ds18b20.h │ └── dht11.h ├── Drivers └── STM32CubeIDE

5.2 主程序逻辑

典型的主循环实现方案:

while(1) { static uint32_t last_read = 0; if(HAL_GetTick() - last_read > 2000) { // 每2秒读取一次 float temp = DS18B20_ReadTemp(); uint8_t humi, temp_dht; if(DHT11_ReadData(&humi, &temp_dht)) { printf("DS18B20 Temp: %.2f°C\r\n", temp); printf("DHT11 Temp: %d°C, Humi: %d%%\r\n", temp_dht, humi); } last_read = HAL_GetTick(); } HAL_Delay(100); }

5.3 调试技巧

常见问题排查方法:

  1. 使用逻辑分析仪捕获单总线时序
  2. 检查电源稳定性(纹波<50mV)
  3. 验证延时函数精度(误差<10%)
  4. 注意GPIO模式切换时序

在项目开发中,我发现DS18B20对时序要求极为严格,特别是在温度转换期间(Tconv)必须保证足够的等待时间。而DHT11则对起始信号的长度更为敏感,实际测试中发现18ms的低电平持续时间是最可靠的触发条件。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 17:30:19

SiameseUIE数学建模应用:从文献中自动提取公式和参数

SiameseUIE数学建模应用&#xff1a;从文献中自动提取公式和参数 1. 引言 数学建模研究者每天都要面对海量的学术文献&#xff0c;从中手动提取数学公式和相关参数既耗时又容易出错。传统方法需要逐页阅读、手动记录&#xff0c;不仅效率低下&#xff0c;还经常出现遗漏或误读…

作者头像 李华
网站建设 2026/4/18 17:27:33

Windows 11 LTSC系统微软商店组件集成技术方案

Windows 11 LTSC系统微软商店组件集成技术方案 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore Windows 11 LTSC&#xff08;长期服务通道&#xff09;…

作者头像 李华
网站建设 2026/4/18 17:21:13

STM32 FOC电机库PID调参避坑指南:为什么你的定点参数调不好?

STM32 FOC电机库PID调参避坑指南&#xff1a;为什么你的定点参数调不好&#xff1f; 调试电机控制系统的PID参数就像在给一台精密仪器做微创手术——参数调整的每一个细节都可能影响最终性能表现。对于使用STM32 FOC电机库的工程师来说&#xff0c;定点PID参数的调试尤其考验技…

作者头像 李华
网站建设 2026/4/18 17:17:12

AGI能力≠人类智能?2026奇点大会首次定义“奇点适配商数(SAQ)”:3个公式+1套校准工具链,立即测算你的系统风险阈值

第一章&#xff1a;2026奇点智能技术大会&#xff1a;AGI的能力评估 2026奇点智能技术大会(https://ml-summit.org) 评估框架的范式转移 本届大会首次发布《AGI能力统一评估基准v3.1》&#xff08;ACE-Bench&#xff09;&#xff0c;摒弃传统单项任务准确率导向&#xff0c;转…

作者头像 李华