DHT11.c文件
#include "DHT11.h"
/*
* 更改DHT11引脚方向
*/
// 输出output
void Dht11_DATA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PB12 */
GPIO_InitStruct.Pin = DHT11_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIO_DHT11, &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 = DHT11_PIN;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIO_DHT11, &GPIO_InitStruct);
}
/*
* DHT11驱动
*/
//复位DHT11
void DHT11_Rst(void)
{
Dht11_DATA_OUT(); //设置为输出
HAL_GPIO_WritePin(GPIO_DHT11, DHT11_PIN, GPIO_PIN_RESET); //拉低引脚
HAL_Delay(20); //延迟20ms
HAL_GPIO_WritePin(GPIO_DHT11, DHT11_PIN, 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(GPIO_DHT11, DHT11_PIN) && retry<100)
{
LED1_PIN_SET;
retry++;
Delay_us(1);
}
if(retry>=100)
return 1;
else
retry=0;
while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIO_DHT11, DHT11_PIN) && retry<100)
{
LED1_PIN_RESET;
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(GPIO_DHT11, DHT11_PIN) && retry<100)
{
retry++;
Delay_us(1);
}
retry=0;
while(GPIO_PIN_RESET==HAL_GPIO_ReadPin(GPIO_DHT11, DHT11_PIN) && retry<100)
{
retry++;
Delay_us(1);
}
Delay_us(40);
if(GPIO_PIN_SET==HAL_GPIO_ReadPin(GPIO_DHT11, DHT11_PIN))
return 1;
else
return 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];
}
}
else
return 1;
return 0;
}
DHT11.h
#ifndef __DHT11_H_
#define __DHT11_H_
/* Private includes ----------------------------------------------------------*/
#include "main.h"
#include "gpio.h"
#include "stdio.h"
#include "stm32f1xx.h"
#include "time_us.h"
#include "OLED_I2C.h"
/* Private define ------------------------------------------------------------*/
#define GPIO_DHT11 GPIOB
#define DHT11_PIN GPIO_PIN_12
/*修改以上管脚*/
#define DHT11_PIN_SET HAL_GPIO_WritePin(GPIO_DHT11,DHT11_PIN,GPIO_PIN_SET) // 设置GPIO为高
#define DHT11_PIN_RESET HAL_GPIO_WritePin(GPIO_DHT11,DHT11_PIN,GPIO_PIN_RESET) // 设置GPIO为低
#define DHT11_READ_IO HAL_GPIO_ReadPin(GPIO_DHT11,DHT11_PIN) // DHT11 GPIO定义
/* Private function prototypes -----------------------------------------------*/
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
mian.c
DHT11_Rst(); //复位DHT11
while(DHT11_Check()){
// OLED_ShowStr(0,2,CntState,1);
// HAL_UART_Transmit(&huart1, CntState, strlen(CntState), 200);
HAL_Delay(500);
}
CntState = "Success!\r\n";
// HAL_UART_Transmit(&huart1, CntState, strlen(CntState), 200);
// OLED_ShowStr(0,2,CntState,1);
HAL_Delay(1000);
// OLED_CLS();
OLED_ShowChar(32,1,':',1);
OLED_ShowChar(32,7,':',1);
OLED_ShowStr(0,0,"Humi",2);
OLED_ShowStr(0,6,"temp",2);
OLED_ShowChar(65,1,'%',1);
OLED_ShowChar(65,7,'C',1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
DHT11_Read_Data(&humidity,&temperature); //检测出温湿度的值
OLED_ShowNum(45,0,humidity,2,2);
OLED_ShowNum(45,6,temperature,2,2);
// sprintf(aTxBuffer,"temperature : %d ^C "
// "humidity : %d %% \r\n", temperature,humidity); //打印温湿度的值
// HAL_UART_Transmit(&huart1,aTxBuffer,strlen((const char*)aTxBuffer),200);
HAL_Delay(500);
}
##DHT11_ check 函数是 监测DHT11会主动拉低
首先主机发送开始信号,即:拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2(20~40us)时间,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间后,开始输出数据。
————————————————
【引用】
原文链接:https://blog.csdn.net/weixin_46364710/article/details/130897555