首页 > 其他分享 >STM32+DHT11监测环境的温湿度

STM32+DHT11监测环境的温湿度

时间:2023-06-11 10:06:38浏览次数:50  
标签:温湿度 us STM32 InitStruct GPIO DHT11 data dht11

【1】DHT11传感器

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

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

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

STM32+DHT11监测环境的温湿度_DHT11

【2】通信协议

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

  1. 主机发送一个开始信号给DHT11,即将数据信号线拉低至少18ms以上。
  2. 主机发出启动信号之后,拉低数据线至少80us,在这个过程中,DHT11将会检测到主机发送的启动信号,并做出回应。
  3. DHT11响应主机发出的启动信号后,会拉高数据信号线至少80us,表示传输数据前的“准备工作”已经完成。
  4. DHT11开始向主机发送数据,每个数据包包含40个位,高位先传输。在数据传输的过程中,DHT11会将数据信号线从低电平转换为高电平,表示1的开始,持续时间26~28us,然后将数据线拉低,表示0的开始,持续时间~70us。
  5. 在发送完40位数据后,DHT11会发送一个校验位。校验位的计算方法是将前四个字节数据相加,求出一个8位校验码,将此校验码与第五个字节进行比较,如果相等,则数据传输成功,否则需要重传数据。
  6. 主机接收到数据后,需要将数据信号线拉高,以结束传输。

【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传感器,并执行一个循环来读取数据。如果读取成功,则将温度和湿度打印到串口终端上,否则输出错误信息。


标签:温湿度,us,STM32,InitStruct,GPIO,DHT11,data,dht11
From: https://blog.51cto.com/u_11822586/6457004

相关文章

  • STM32使用寄存器实现点灯操作
    1.配置RCC_APB2ENR(见参考手册7.3.7)2.配置GPIOC_CRH(见参考手册8.2.2)3.配置GPIOC_ODR(见参考手册8.2.4) #include"stm32f10x.h"//Deviceheaderintmain(void){ RCC->APB2ENR=0x00000010; GPIOC->CRH=0x00300000; GPIOC->ODR=0x0000000......
  • STM32通过ADC1读取光敏电阻的值转换光照强度
    【1】光敏电阻的原理光敏电阻是一种半导体元件,它的电阻值会随着照射在其表面的光线强度的变化而发生改变。当光线越强,光敏电阻的电阻值就越小;当光线较弱或没有光照射时,电阻值就会增大。光敏电阻广泛应用于光电控制、光度计、自动调节亮度灯等领域。常见的光敏电阻有硫化镉(CdS)光敏电......
  • 野火STM32 读写内部FLASH
    解锁、上锁函数1voidFLASH_Unlock(void);2voidFLASH_Lock(void);擦除函数:1FLASH_StatusFLASH_ErasePage(uint32_tPage_Address);2FLASH_StatusFLASH_EraseAllPages(void);3FLASH_StatusFLASH_EraseOptionBytes(void);写入函数:1FLASH_StatusFLASH_Progra......
  • STM32新建工程
     1.到ST公司官网(www.st.com)下载固件库https://www.st.com/zh/embedded-software/stm32-standard-peripheral-libraries.html2.为了方便管理,新建一个文件夹用来存放项目,否则会显得混乱3.打开Keil5-Project-new μVisionProject-选中刚刚创建的文件夹-给工程文件命名-......
  • STM32cubemx配置驱动DHT11模块
    (文章目录)前言本篇文章将带大家学习使用DHT11湿温度模块,使用这个模块可以获取当前的温度和湿度数据。DHT11可以用于智能家居,蔬菜大棚等项目当中适用范围广。一、DHT11模块介绍DHT11是一种数字式温湿度传感器,由杜邦公司推出。它可以测量环境中的温度和湿度,并将测量结果以数字......
  • stm32f103实现uart收发数据操作
      //stm32f103c8t6实现usart接收到0xFF0xFF0xCE0xCE,//发送0xEE0xEE0x010xCE//然后PA6输出高电平,否则为低电平//中断写法#include"stm32f10x.h#include"stm32f10x_usart.h"#defineRX_BUFFER_SIZE4uint8_trxBuffer[RX_BUFFER_SIZE];uint8_ttxBuffer[]={0......
  • 明解STM32—GPIO应用设计篇之IO外部中断EXTI原理及使用方法
    ​一、前言        在之前针对STM32的GPIO相关API函数及配置使用进行了详细的介绍,GPIO作为输入引脚时,调用相关读信号引脚函数接口就可以在程序的循环中,轮询的对输入信号进行读取检测操作,除了轮询的方式访问输入引脚,还可以通过另外一种叫做外部中断的方式来对引脚的输入信......
  • stm32+sx1268 LORA通信
    前言:由于亿佰特的lora代码不好移植,基于stm8且是IAR编译器,对于代码的处理很大困难。所以我通过搜索资料发现了泽耀科技的同配置的lora模块写了关于stm32的代码。在实验中,我将买回来的lora模块的引脚按照手册上的需要引出并打板焊接(SPI通信的lora模块),通过stm32连接lora,lora的天线......
  • stm32 sdio
    SDIO学习笔记SDIO简介SDIOstm32驱动stm32的SDIO驱动参考st官方的参考例程,其中详细说明了如何操作,官方的文档翻译如下:1如何使用此设备它实现了一个高级通信层,用于从/向该存储器进行读写。所需的STM32硬件资源(SDIO和GPIO)在stm324xg_eval.h文件中定义,并在stm324xg_eval.c文件......
  • 将stm32 flash和栈相结合,将栈底位置设置成flash地址,可不可以?
      在使用stm32产生了一个疑问,可不可以将栈底位置设置成flash的某个具体位置,这样就可以将参数写入读取,于是便探寻可行性。 在STM32中,Flash存储器用于存放程序代码,而栈通常用于存放临时数据和变量。根据STM32架构设计,Flash和SRAM两者之间是相互独立的,Flash的写入和读取速度相......