Skip to content

温湿度传感器 DHT11

1. 硬件连接

alt text

2. CubeMX生成代码

MCU 的GPIO的状态 alt text

在这里我们把IO配置成开漏,这样既能输入,也能输出。驱动靠外部的上拉电阻,在温湿度传感器的data PIN 上有一个上拉电阻提供驱动能力。

alt text

3. 编写代码

串口配置代码

c
#include <stdio.h>
 //重定向c库函数printf到串口USARTx,重定向后可使用printf函数
 int fputc(int ch, FILE *f)
 {
     /* 发送一个字节数据到串口USARTx */
     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
     return (ch);
 }

 //重定向c库函数scanf到串口USARTx,重写向后可使用scanf、getchar等函数
 int fgetc(FILE *f)
 {
     int ch;
     /* 等待串口输入数据 */
     while (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) == RESET);
     HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
     return (ch);
 }

us 延时函数, 注意:此代码只能运行在--->主频72M,F103c8t6 。更换 芯片/频率 则有可能失效,导致通信异常!!!

C
void delay_us(uint32_t time)
{
  time *= 10;
	while(time)
		time--;
}

温湿度模块控制函数

C

#define DHT11_PIN      GPIO_PIN_0  
#define DHT11_IO      GPIOA     

void DHT11_Start()
{
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_RESET);
    HAL_Delay(20);                                               //拉低总线至少 18ms
    HAL_GPIO_WritePin(DHT11_IO, DHT11_PIN, GPIO_PIN_SET);

    while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));               //上一步将总线设为高电平,等待DHT11响应低电平
    while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));              //上一步DHT11响应低电平,等待DHT11拉高总线
    while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));               //上一步DHT11拉高了总线,等待DHT11拉低总线,开始传送数据
}

uint8_t DHT_Read_Byte(void)  //从DHT11读取一位(8字节)信号
{
    uint8_t i;
    uint8_t ReadData = 0;    //ReadData用于存放8bit数据,即8个单次读取的1bit数据的组合
    uint8_t temp;            //临时存放信号电平(0或1)

    for(i=0;i<8;i++){
        while(!HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
        delay_us(50);
        if(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN) == 1){
            temp = 1;
            while(HAL_GPIO_ReadPin(DHT11_IO, DHT11_PIN));
        }else{
            temp = 0;
        } 
        ReadData = ReadData << 1;
        ReadData |= temp;
    }
    return ReadData;
}

void DHT_Read()
{
    uint8_t i;
		uint8_t Data[6] = {0};
	
	
    DHT11_Start();

    for(i= 0;i < 5;i++){
        Data[i] = DHT_Read_Byte();
    }
    if((Data[0]+Data[1]+Data[2]+Data[3])==Data[4])
    {		
			float result = Data[0] + (float)Data[1] / 10.0f;
			printf("湿度:%.1f ,\n", result); 

			result = Data[2] + (float)Data[3] / 10.0f;
			printf("温度:%.1f\r\n", result); 
			
    }else{
        printf("ERROR DATA\r\n");
    }
    HAL_Delay(2000);
}

主函数

C

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	DHT_Read();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

4. 后记

  1. 代码中使用了开漏的GPIO配置方式,实现了读写功能,无需重新初始化GPIO来实现读写功能。
  2. 代码中的浮点数仅显示一位小数,显示温湿度。如果位数超过,则显示异常。