一、配置
二、代码
dht11.c
/** dht11.c** Created on: Aug 19, 2024* Author: Administrator*/#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
/**TIM3定时器实现us级延时*/
void Delay_us(uint16_t delay)
{__HAL_TIM_DISABLE(&htim3);__HAL_TIM_SET_COUNTER(&htim3,0);__HAL_TIM_ENABLE(&htim3);uint16_t curCnt=0;while(1){curCnt=__HAL_TIM_GET_COUNTER(&htim3);if(curCnt>=delay)break;}__HAL_TIM_DISABLE(&htim3);
}/** 更改DHT11引脚方向*/
// 输出output
void Dht11_DATA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/*Configure GPIO pin : PB12 */GPIO_InitStruct.Pin = GPIO_PIN_12;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}// 输入input
void Dht11_DATA_IN(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/*Configure GPIO pin : PB12 */GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pin = GPIO_PIN_12;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/** DHT11驱动*/
//复位DHT11
void DHT11_Rst(void)
{Dht11_DATA_OUT(); //设置为输出HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET); //拉低引脚HAL_Delay(20); //延迟20msHAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET); //拉高引脚Delay_us(30); //延迟30us
}//等待DHT11回应
//返回值:1代表未检测到存在,0代表检测到存在
uint8_t DHT11_Check(void)
{uint8_t retry=0;Dht11_DATA_IN(); //设置为输入while(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100){retry++;Delay_us(1);}if(retry>=100)return 1;elseretry=0;while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100){retry++;Delay_us(1);}if(retry>=100)return 1;return 0;
}//从DHT11读取一个位
//返回值:1/0
uint8_t DHT11_Read_Bit(void)
{uint8_t retry=0;while(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100){retry++;Delay_us(1);}retry=0;while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) && retry<100){retry++;Delay_us(1);}Delay_us(40);if(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12))return 1;elsereturn 0;
}//从DHT11读取一个字节
//返回值:读取到的字节数据(8位)
uint8_t DHT11_Read_Byte(void)
{uint8_t dat=0;for(uint8_t i=0;i<8;i++){dat <<= 1;dat |= DHT11_Read_Bit();}return dat;
}//从DHT11读取一次数据
//humi:湿度值,temp:温度值
//返回值:0代表正常,1代表读取失败
uint8_t DHT11_Read_Data(uint8_t* humi,uint8_t* temp)
{uint8_t buf[5];DHT11_Rst();if(DHT11_Check() == 0){for(uint8_t i=0;i<5;i++)buf[i]=DHT11_Read_Byte();if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]){*humi=buf[0]; //这里省略小数部分*temp=buf[2];}}elsereturn 1;return 0;
}
dht11.h
/** dht11.h** Created on: Aug 19, 2024* Author: Administrator*/#ifndef INC_DHT11_H_
#define INC_DHT11_H_void Delay_us(uint16_t delay); //通过TIM3定时器微秒级延时
void Dht11_DATA_OUT(void); //设置数据交互口为输出
void Dht11_DATA_IN(void); //设置数据交互口为输入
void DHT11_Rst(void); //复位DHT11
uint8_t DHT11_Check(void); //DHT11状态反馈
uint8_t DHT11_Read_Bit(void); //读DHT11一位数据
uint8_t DHT11_Read_Byte(void); //读DHT11一字节数据
uint8_t DHT11_Read_Data(uint8_t* humi,uint8_t* temp); //DHT11数据显示#endif /* INC_DHT11_H_ */
main.c
/* USER CODE BEGIN Includes */
#include <stdio.h> //sprintf函数头文件
#include <string.h> //strlen函数头文件
#include "dht11.h"
/* USER CODE END Includes *//* USER CODE BEGIN 1 */uint8_t temperature = 1; //温度值uint8_t humidity = 1; //湿度值char* CntState = "No Connect!\r\n"; //连接状态uint8_t aTxBuffer[50]; //打印信息/* USER CODE END 1 *//* USER CODE BEGIN 2 */DHT11_Rst(); //复位DHT11while(DHT11_Check()) //检测DHT11连接{HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);CntState = "Fail!\r\n";HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);HAL_Delay(500);}CntState = "Success!\r\n";HAL_UART_Transmit(&huart1, (uint8_t *)CntState, strlen(CntState), 200);/* USER CODE END 2 *//* USER CODE BEGIN WHILE */while (1){DHT11_Read_Data(&humidity,&temperature); //检测出温湿度的值sprintf(aTxBuffer,"temperature : %d ^C ""humidity : %d %% \r\n", temperature,humidity); //打印温湿度的值HAL_UART_Transmit(&huart1,aTxBuffer,strlen((const char*)aTxBuffer),200);HAL_Delay(500);/* USER CODE END WHILE */
三、其他
参考教程 http://t.csdnimg.cn/pDPY5