【传感器】代码——DHT11温湿度传感器

发布于:2025-05-10 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

一、代码流程

二、模块.c代码

三、模块.h代码

四、主函数代码


一、代码流程

1.模块复位:主机发送开始通信时序,从机做出响应(需检测是否有响应)

2.MCU读取1Bit数据

3.MCU读取1Byte数据

4.MCU读取8Byte数据组成完整Data,每读一次Data前都要开始通信流程

二、模块.c代码

#include "dht11.h"

/********************等待从机响应:返回0表示初始化成功*************************/
uint8_t DHT11_Reset(void)
{
  RCC_APB2PeriphClockCmd(DHT11_CLK, ENABLE);
  
  GPIO_InitTypeDef GPIO_InitStruct;                    //主机控制引脚
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStruct.GPIO_Pin = DHT11_PIN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DHT11_PORT, &GPIO_InitStruct);

  GPIO_ResetBits(DHT11_PORT, DHT11_PIN);               //主机发出开始通信的信号
  Delay_ms(20);
  GPIO_SetBits(DHT11_PORT, DHT11_PIN);
  Delay_us(13);
  
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //主机释放引脚控制权,转为输入模式监听引脚电平
  GPIO_InitStruct.GPIO_Pin = DHT11_PIN;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DHT11_PORT, &GPIO_InitStruct);  
    
  uint8_t time = 0;

  while( (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0) && time < 100 )    //检测响应低电平是否正常
  {
    Delay_us(1);
    time++;
  }
  if(time >= 100)
  {
    return 1; 
  }
  else
  {
    time = 0;  
  }
   
  while( (GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1) && time < 100)    //检测响应高电平是否正常
  {
    Delay_us(1);
    time++;
  }
  if(time >= 100)
  {
    return 1;
  }
  else
  {
    time = 0;  
  } 
  
  return 0;
}

/**************************读1Bit*************************************/
uint8_t MCU_Read_Bit(void)
{ 
  while( GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1 );    //检测低电平到来
  while( GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 0 );    //检测高电平到来
  
  Delay_us(35);
  if( GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) == 1 )        //直接读取35us后的数据
  {
    return 1;
  }
  else
  {
    return  0;  
  }
}

/**************************读1Byte****************************************/
uint8_t MCU_Read_Byte(void)
{
  uint8_t tool = 0x80;
  uint8_t Byte = 0;
  for(tool = 0x80; tool != 0; tool >>=1 )                      //DHT11数据高位先行,故从高位到低位读取数据
  {
    if( MCU_Read_Bit() == 1 )
      Byte |= tool;
    else
      Byte &= ~tool;
  }
  return Byte;
}

/*****************读数据:返回0表示读取数据正确***********************/
uint8_t MCU_Read_Data(uint8_t* humidity, uint8_t* temperature)
{
  uint8_t Data[5] = {0};
  uint8_t i = 0;

  if( DHT11_Reset() == 0 )                                         //每次读数据前都要重新开始通信时序,不然只会有一次数据显示
  {
    for( i = 0; i < 5; i++)
    {
      Data[i] = MCU_Read_Byte();                                   //将数据存入数组
    }
    if( (Data[0] + Data[1] + Data[2] + Data[3]) == Data[4] )       //如果校验位正确
    {
      *humidity = Data[0];                                         //读出数据
      *temperature = Data[2];
      return 0;                                                    //返回0表示读数据正确
    }      
  }
  return 1;                                                        //返回1表示读数据存在错误
}

三、模块.h代码

#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "serial.h"

#define DHT11_CLK      RCC_APB2Periph_GPIOB
#define DHT11_PORT     GPIOB
#define DHT11_PIN      GPIO_Pin_14

uint8_t DHT11_Reset(void);
uint8_t MCU_Read_Bit(void);
uint8_t MCU_Read_Byte(void);
uint8_t MCU_Read_Data(uint8_t* humidity, uint8_t* temperature);

#endif

四、主函数代码

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "DHT11.h"

int main(void)
{
	OLED_Init();	
  uint8_t test = 1;      //接收DHT11初始化是否成功的返回值
	uint8_t humidity = 0, temperature = 0; 
	while (1)
	{

    test = MCU_Read_Data(&humidity, &temperature);
    if(test == 0)
    {
      OLED_ShowNum(1, 1, humidity, 2);
      OLED_ShowNum(2, 1, temperature, 2);  
      Delay_ms(500);      
    }
    OLED_ShowHexNum(3, 1, test, 1);
	}
}


网站公告

今日签到

点亮在社区的每一天
去签到