STM32F407+DHT11采集数据

本文详细介绍了DHT11数字湿温度传感器的工作原理,包括数据结构、传输时序以及与单片机的接口代码。重点展示了如何通过单总线与DHT11通信并解析数据,以及提供了一个完整的C语言代码示例和测试结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 1、DHT11简介

        DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。

        DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向
传输。其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数
数据+8bit 温度小数数据+8bit 校验和。
其中校验和数据为前四个字节相加。

2、DHT11传输时序

        DHT11和MCU的一次通信最大为3ms左右,建议主机连续读取时间间隔不要小于 100ms。

图2.1 DHT11 数据发送流程

### STM32F407DHT11传感器集成的驱动代码示例 对于STM32F407微控制器与DHT11温湿度传感器的集成,可以通过GPIO接口实现通信。以下是一个完整的驱动代码示例以及相关说明。 #### GPIO初始化配置 为了使能DHT11的功能,需要先通过GPIO设置其引脚模式为输入或输出。这里假设使用PA0作为连接DHT11数据线: ```c #include "stm32f4xx_hal.h" void DHT11_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); // 启用GPIOA时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; // 设置PA0为推挽输出模式 GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽输出 GPIO_InitStruct.Pull = GPIO_NOPULL; // 不带上下拉电阻 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 低速模式即可满足需求 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 上述代码完成了对DHT11数据线的初始化工作[^1]。 #### 数据读取函数 接下来定义用于启动测量并获取温湿度数据的核心逻辑: ```c #define MAX_TIME 100 uint8_t DHT11_Start() { uint8_t response; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 主机拉低至少18ms HAL_Delay(20); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 上升沿触发DHT11响应 __NOP(); __NOP(); // 等待DHT11拉低总线约80us uint32_t count = 0; while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) && (++count < MAX_TIME)); if(count >= MAX_TIME){ return ERROR; } // 等待DHT11释放总线约80us count = 0; while(!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)) && (++count < MAX_TIME)); if(count >= MAX_TIME){ return ERROR; } return SUCCESS; } // 定义接收缓冲区存储接收到的数据字节 uint8_t data[5]; uint8_t DHT11_Read_Data(){ for(int i=0;i<5;i++)data[i]=0; if(DHT11_Start()==ERROR)return ERROR; for(uint8_t i=0;i<5;i++){ for(uint8_t j=0;j<8;j++){ while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)); // 等待高电平到来 delay_us(40); // 延迟固定时间判断高低位 if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0)){ data[i]|=(1<<(7-j)); // 如果此时仍保持高位则记录该bit为&#39;1&#39; }else{ data[i]&=~(1<<(7-j)); // 反之为&#39;0&#39; } while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0));//等待信号结束直至再次变为低电平 } } if(data[4]==((data[0]+data[1]+data[2]+data[3])&0xFF)) return OK; else return CHECKSUM_ERROR; } ``` 以上实现了从DHT11设备处采集原始数据包的过程,并验证校验码是否正确[^2]。 #### 主程序调用实例 最后,在`main()`函数里周期性地执行这些操作来显示当前环境状况: ```c int main(void){ HAL_Init(); SystemClock_Config(); DHT11_GPIO_Init(); while (1){ if(DHT11_Read_Data()==OK){ printf("Humidity: %d.%d %% , Temperature: %d.%d *C\r\n", data[0],data[1]/10,data[2],data[3]/10); } HAL_Delay(2000); // 每隔两秒刷新一次屏幕上的数值 } } ``` 此部分展示了如何利用前面编写的子功能模块完成整个系统的搭建[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值