STM32+DHT11监测环境的温湿度

发布者:beta13最新更新时间:2024-05-10 来源: elecfans关键字:STM32  DHT11  监测环境  温湿度 手机看文章 扫描二维码
随时随地手机看文章

【1】DHT11传感器

DHT11是一种数字温湿度传感器,能够通过数字信号输出当前环境的温度和湿度值。DHT11可以通过一条数据信号线连接到微控制器或其他外设,从而实现温湿度的实时测量和数据读取。


DHT11采用单总线通信协议,只需要连接一个数字信号线和两个电源线,即可实现传感器的数据读取。传感器本身具有一定的温度和湿度校准能力,因此输出的数据比较可靠。



DHT11传感器的测量范围为0~50°C的温度和20%~90%的相对湿度,测量精度为±2°C和±5%RH。


【2】通信协议

DHT11采用单总线通信协议,使用一条数据信号线来传输数据,其中包括起始信号、数据位和校验位。通信协议如下:


主机发送一个开始信号给DHT11,即将数据信号线拉低至少18ms以上。

主机发出启动信号之后,拉低数据线至少80us,在这个过程中,DHT11将会检测到主机发送的启动信号,并做出回应。

DHT11响应主机发出的启动信号后,会拉高数据信号线至少80us,表示传输数据前的“准备工作”已经完成。

DHT11开始向主机发送数据,每个数据包包含40个位,高位先传输。在数据传输的过程中,DHT11会将数据信号线从低电平转换为高电平,表示1的开始,持续时间2628us,然后将数据线拉低,表示0的开始,持续时间70us。

在发送完40位数据后,DHT11会发送一个校验位。校验位的计算方法是将前四个字节数据相加,求出一个8位校验码,将此校验码与第五个字节进行比较,如果相等,则数据传输成功,否则需要重传数据。

主机接收到数据后,需要将数据信号线拉高,以结束传输。

【3】读取DHT11温湿度数据

以下是一个读取DHT11传感器的温度和湿度示例代码:


Copy Code#include 'stm32f10x.h'

#include 'dht11.h'

#define DHT11_GPIO_PORT GPIOB

#define DHT11_GPIO_PIN GPIO_Pin_12

void delay_us(uint32_t us)

{

  us *= (SystemCoreClock / 1000000) / 5;

  while (--us);

}

void dht11_start(void)

{

  GPIO_InitTypeDef GPIO_InitStruct;

  GPIO_InitStruct.GPIO_Pin = DHT11_GPIO_PIN;

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);

  /* 发送开始信号 */

  GPIO_ResetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN);

  delay_us(18000);

  GPIO_SetBits(DHT11_GPIO_PORT, DHT11_GPIO_PIN);

  delay_us(40);

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);

}

uint16_t dht11_read_bit(void)

{

  uint16_t retry = 0;

  while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == RESET) {

    retry++;

    if (retry > 1000) {

      return 0;

     }

    delay_us(1);

   }

  retry = 0;

  while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == SET) {

    retry++;

    if (retry > 1000) {

      return 0;

     }

    delay_us(1);

   }

  if (retry < 30) {

         return 0;

     } else {

         return 1;

     }

 }

 

 uint8_t dht11_read_byte(void)

 {

     uint8_t i;

     uint8_t data = 0;

 

     for (i = 0; i < 8; i++) {

         data <<= 1;

         if (dht11_read_bit()) {

             data |= 0x01;

         }

     }

 

     return data;

 }

 

 uint8_t dht11_read_data(dht11_data_t *data)

 {

     uint8_t i;

     uint8_t buf[5];

     uint8_t checksum = 0;

 

     dht11_start();

 

     if (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == RESET) {

         /* 等待DHT11响应 */

         while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == RESET);

 

         /* 等待DHT11发射数据 */

         while (GPIO_ReadInputDataBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN) == SET);

 

         /* 接收数据 */

         for (i = 0; i < 5; i++) {

             buf[i] = dht11_read_byte();

         }

 

         /* 校验和 */

         checksum = buf[0] + buf[1] + buf[2] + buf[3];

 

         if (checksum == buf[4]) {

             data->humidity = buf[0];

      data->temperature = buf[2];

      return 1;

     }

   }

  return 0;

}

int main(void)

{

  dht11_data_t data;

  GPIO_InitTypeDef GPIO_InitStruct;

  /* 使能GPIOB时钟 */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  /* 配置DHT11引脚为输入模式 */

  GPIO_InitStruct.GPIO_Pin = DHT11_GPIO_PIN;

  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;

  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);

  while (1) {

    if (dht11_read_data(&data)) {

      printf('Temperature: %d°C   Humidity: %d%%n', data.temperature, data.humidity);

     } else {

      printf('Error reading data from DHT11.n');

     }

    delay_us(2000000);

   }

}

在这个示例代码中,首先定义了一个

dht11_data_t

结构体,用于保存读取的温度和湿度数据。然后,编写了一些函数来执行DHT11读取操作。


delay_us()

函数是一个简单的延迟函数,用于等待一定量的时间。需要精确地计算一个微秒的延迟,并在循环中使用该延迟来等待一段时间。


dht11_start()

函数用于发送DHT11的开始信号。将DHT11引脚配置为输出模式,并发送18毫秒的低电平信号,然后再发送40微秒的高电平信号。


dht11_read_bit()

函数用于读取DHT11传输的数据位。等待DHT11输出信号的变化,并根据变化的时间来判断数据位的值。如果一个数据位的响应时间小于30微秒,则被判定为0,否则为1。


dht11_read_byte()

函数用于读取一个字节的数据(8个数据位)。通过调用

dht11_read_bit()

函数8次来读取每个数据位,并将结果组合成一个字节。


dht11_read_data()

函数用于读取整个DHT11数据包,包括温度、湿度和校验和。首先调用

dht11_start()

函数发送开始信号,然后等待DHT11发送数据。使用

dht11_read_byte()

函数读取5个字节的数据,并验证校验和以确保数据完整和正确。


最后,在

main()

函数中,初始化GPIO口和DHT11传感器,并执行一个循环来读取数据。如果读取成功,则将温度和湿度打印到串口终端上,否则输出错误信息。


关键字:STM32  DHT11  监测环境  温湿度 引用地址:STM32+DHT11监测环境的温湿度

上一篇:STM32采集传感器数据通过冒泡排序取稳定值
下一篇:基于STM32物联网开发板(2)--语音播报SYN6288

推荐阅读最新更新时间:2024-11-02 11:26

STM32程序之MAX6675热电偶温度读取
第一次编写STM32程序,有很多问题请教,我想把MAX6675的SO的数据读出来转换成实际温度,用串口工具读出来。 电路是标准的SPI接法,SO没有上拉电阻。 MISO脚配置为浮空,没有做内部上拉。 用HAL很简单,CS拉低以后,一个SPI读两个字节进来,然后就是凑成12位,换算。 MAX6675文档强调是在时钟下降沿读取数据,因此将SPI2配置为: view plain copyhspi2.Init.CLKPolarity = SPI_POLARITY_LOW; hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.BaudRatePrescaler = SPI_BA
[单片机]
stm32 hal库不定长接收数据
使用 IDLE 中断接收,稍微修改了hal库,但是都是在begin end中修改,重新在cube中生成代码不会去掉这部分内容,不见原理,原理部分请参考编程手册,只讲做法。 1.在stm32f4xx_it,c中修改 void USART1_IRQHandler(void) { /* USER CODE BEGIN USART1_IRQn 0 */ uint32_t isrflags = READ_REG(huart1.Instance- SR); uint32_t cr1its = READ_REG(huart1.Instance- CR1); if(((isrflags & USART_SR_IDLE) !=
[单片机]
STM32下SPI模式通过MAX7219驱动8位数码管显示模块
借鉴的地方: 1、正点原子的“ALIENTEK MINISTM32 实验20 SPI实验” 2、 STM32 硬件SPI max7219 8位数码管显示模块 http://www.openedv.com/posts/list/46179.htm 工具: STM32F103RCT6开发板;MAX7219 8位数码管显示模块: 数码管模块电路图:(店家https://item.taobao.com/item.htm?spm=a1z09.2.0.0.FiSjlX&id=41059249086&_u=cjnajni5a96提供) MAX7219中文说明可以借鉴: http://wenku.baidu.co
[单片机]
<font color='red'>STM32</font>下SPI模式通过MAX7219驱动8位数码管显示模块
STM32串口使用
STM32的串口大多数情况下会预留USART1作为烧录接口或者调试接口。 通常做法是调用 stdio.h 将串口的输入输出重新定向,可以直接调用printf. 代码如下: /** ****************************************************************************** * 文件名程: bsp_usartx.c * 版 本: V1.0 * 编写日期: * 功 能: 串口底层驱动程序 */ /* 包含头文件 ----------------------------------------------------------------*
[单片机]
STM32的bootloader IAP编程
首先谈谈stm32的ISP和IAP区别和联系。 ISP(In-System Programming)在系统可编程,指电路板上的空白器件可以编程写入最终用户代码, 而不需要从电路板上取下器件,已经编程的器件也可以用ISP方式擦除或再编程。IAP(In-Application Programming) 指MCU可以在系统中获取新代码并对自己重新编程,即可用程序来改变程序。ISP和IAP技术是未来仪器仪表的发展方向。 1 ISP和IAP的工作原理 ISP的实现相对要简单一些,一般通用做法是内部的存储器可以由上位机的软件通过串口来进行改写。对于单片机来讲可以通过SPI或其它的串行接口接收上位机传来的数据并写入存储器中。所以即使我们将
[单片机]
STM32第一次学习——使用库函数点亮LED灯
使用库函数点亮LED灯 led.h #ifndef _LED_H #define _LED_H #include stm32f10x.h #define LED_PORT_RCC RCC_APB2Periph_GPIOC #define LED_PIN GPIO_Pin_0 #define LED_PORT GPIOC void LED_Init(void); #endif led.c #include led.h void LED_Init() { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_G
[单片机]
一种便携式多参数环境监测仪的设计
摘要:介绍一种基于MSP430系列超低功耗单片机的多参数环境监测仪,详细阐明了环境参数传感器的选取、监测仪软硬件的设计与实现方法。该仪器充分利用MSP430单片机自身资源,具有小型便携、高性能、低功耗、可编程等优点,可广泛应用于诸多领域的环境参数监测与保护。 关键词:MSP430单片机 环境参数 监测仪 低功耗 本文以智能建筑为应用背景,介绍一种通用性很强的便携式多参数环境监测仪。它以MSP430F437超低功耗单片机为核心,配置新式的微型低功耗传感器,实现了建筑物内温度、湿度、光照度、有害气体浓度等参数的采集处理、存储、通信等功能。文中详细阐明了传感器的选取、硬件结构、软件流程等相关技术,并指出该仪器的特点和优势。 1
[应用]
STM32低功耗Demo
本例展示了如何使用NVIC固件函数库来来展示Cortex-M3低功耗性能(WFE和WFI)。 本例使用了3条外部中断线路,线路3--KEY2,线路4--KEY3和线路13--JOY,在每一个信号下降研做为中断发生源或者事件源(event),其中外部中断线路3和13被设置为中断而线路4被设置成事件。用户需要在main程序开头的5个定义(define)语句中选择定义一个来决定进入那种低功耗模式。 这些选择为: - Wait For Interrupt (WFI) Sleep On Exit:先按JOY,再加任一中断,即可进入SLEEP =》无法唤醒 只有key2可进入中断 选择“#define
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved