DHT11代码无阻塞读取
·



以下是DHT11.c文件,包含阻塞和非阻塞
#include "DHT11.h"
static void DHT11_Mode_IPU(void);
static void DHT11_Mode_Out_PP(void);
DHT11_Data_TypeDef DHT11_Data;
uint8_t DHT11_Flag = 1;
uint8_t temp;
void DHT11_Init ( void )
{
RCC_APB2PeriphClockCmd(DHT11_GPIO_CLK, ENABLE);
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
}
static void DHT11_Mode_IPU(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.GPIO_Pin = DHT11_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DHT11_GPIO_PORT, &GPIO_InitStruct);
}
static void DHT11_Mode_Out_PP(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
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);
}
static uint8_t DHT11_ReadByte ( void )
{
uint8_t i, temp=0;
for(i=0;i<8;i++)
{
while(DHT11_R_DATA==DHT11_DATA_RESET);
Delay_us(40);
if(DHT11_R_DATA==DHT11_DATA_SET)
{
while(DHT11_R_DATA==DHT11_DATA_SET);
temp|=(uint8_t)(0x01<<(7-i));
}
else
{
temp&=(uint8_t)~(0x01<<(7-i));
}
}
return temp;
}
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef *DHT11_Data)
{
uint8_t temp;
uint16_t humi_temp;
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_RESET);
Delay_ms(20);
DHT11_W_DATA(DHT11_DATA_SET);
Delay_us(30);
DHT11_Mode_IPU();
Delay_us(30);
if(DHT11_R_DATA==DHT11_DATA_RESET)
{
while(DHT11_R_DATA==DHT11_DATA_RESET);
while(DHT11_R_DATA==DHT11_DATA_SET);
DHT11_Data->humi_high8bit= DHT11_ReadByte();
DHT11_Data->humi_low8bit = DHT11_ReadByte();
DHT11_Data->temp_high8bit= DHT11_ReadByte();
DHT11_Data->temp_low8bit = DHT11_ReadByte();
DHT11_Data->check_sum = DHT11_ReadByte();
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
humi_temp=DHT11_Data->humi_high8bit*100+DHT11_Data->humi_low8bit;
DHT11_Data->humidity =(float)humi_temp/100;
humi_temp=DHT11_Data->temp_high8bit*100+DHT11_Data->temp_low8bit;
DHT11_Data->temperature=(float)humi_temp/100;
temp = DHT11_Data->humi_high8bit + DHT11_Data->humi_low8bit +
DHT11_Data->temp_high8bit+ DHT11_Data->temp_low8bit;
if(DHT11_Data->check_sum==temp)
{
return 1;
}
else return -1;
}
else
return -1;
}
uint8_t DHT11_GetFlag()
{
if(DHT11_Flag == 1)
{
return 1;
}
return 0;
}
void DHT11_GetVlaue(DHT11_Data_TypeDef *DHT11_Data)
{
uint16_t humi_temp;
DHT11_Data->humi_high8bit= DHT11_Data->buf[0];
DHT11_Data->humi_low8bit = DHT11_Data->buf[1];
DHT11_Data->temp_high8bit= DHT11_Data->buf[2];
DHT11_Data->temp_low8bit = DHT11_Data->buf[3];
DHT11_Data->check_sum = DHT11_Data->buf[4];
humi_temp=DHT11_Data->humi_high8bit*100+DHT11_Data->humi_low8bit;
DHT11_Data->humidity =(float)humi_temp/100;
humi_temp=DHT11_Data->temp_high8bit*100+DHT11_Data->temp_low8bit;
if(DHT11_Data->temp_low8bit & (0x01<<8))
{
DHT11_Data->temperature = -(float)humi_temp/100;
}
else
{
DHT11_Data->temperature = (float)humi_temp/100;
}
DHT11_Flag = 0;
}
uint8_t DHT11_Tick(DHT11_Data_TypeDef *DHT11_Data)
{
static uint8_t DHT11_S = 0;
static uint8_t i = 0;
static uint8_t j = 0;
static uint16_t time = 0;
static uint16_t timeout = 0;
if(time > 0)
{
time--;
return 0;
}
timeout++;
if(DHT11_S == 0)
{
if(DHT11_Flag == 0)
{
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_RESET);
time = 2000;
DHT11_S = 1;
timeout = 0;
}
}
else if(DHT11_S == 1)
{
DHT11_W_DATA(DHT11_DATA_SET);
time = 3;
DHT11_S = 2;
timeout = 0;
}
else if(DHT11_S == 2)
{
DHT11_Mode_IPU();
if(DHT11_R_DATA==DHT11_DATA_RESET)
{
DHT11_S = 3;
timeout = 0;
}
else if(timeout > 10)
{
DHT11_S = 0;
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
timeout = 0;
}
}
else if(DHT11_S == 3)
{
if((DHT11_R_DATA==DHT11_DATA_SET))
{
DHT11_S = 4;
timeout = 0;
}
else if(timeout > 10)
{
DHT11_S = 0;
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
timeout = 0;
}
}
else if(DHT11_S == 4)
{
if((DHT11_R_DATA==DHT11_DATA_RESET))
{
DHT11_S = 5;
timeout = 0;
}
else if(timeout > 10)
{
DHT11_S = 0;
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
timeout = 0;
}
}
else if(DHT11_S == 5)
{
if((DHT11_R_DATA==DHT11_DATA_SET))
{
DHT11_S = 6;
time = 4;
timeout = 0;
}
else if(timeout > 10)
{
DHT11_S = 0;
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
timeout = 0;
}
}
else if(DHT11_S == 6)
{
if(DHT11_R_DATA==DHT11_DATA_SET)
{
temp|=(uint8_t)(0x01<<(7-i));
}
i++;
if(i == 8)
{
i = 0;
DHT11_Data->buf[j] = temp;
j++;
temp = 0;
if(j == 5)
{
j = 0;
uint8_t sum = DHT11_Data->buf[0] + DHT11_Data->buf[1] + DHT11_Data->buf[2] + DHT11_Data->buf[3];
if(sum == DHT11_Data->buf[4])
{
DHT11_Flag = 1;
}
else
{
DHT11_Flag = 0;
}
DHT11_Mode_Out_PP();
DHT11_W_DATA(DHT11_DATA_SET);
DHT11_S = 0;
timeout = 0;
}
}
DHT11_S = 4;
timeout = 0;
}
return DHT11_S;
}
DHT11.h
#ifndef __DHT11_H__
#define __DHT11_H__
#include "stm32f10x.h"
#include "Delay.h"
typedef struct
{
uint8_t humi_high8bit;
uint8_t humi_low8bit;
uint8_t temp_high8bit;
uint8_t temp_low8bit;
uint8_t check_sum;
uint8_t buf[5];
float humidity;
float temperature;
} DHT11_Data_TypeDef;
#define DHT11_GPIO_PORT GPIOG
#define DHT11_GPIO_PIN GPIO_Pin_11
#define DHT11_GPIO_CLK RCC_APB2Periph_GPIOG
#define DHT11_DATA_SET 1
#define DHT11_DATA_RESET 0
#define DHT11_W_DATA(x) GPIO_WriteBit(DHT11_GPIO_PORT, DHT11_GPIO_PIN, (BitAction)(x))
#define DHT11_R_DATA GPIO_ReadInputDataBit(DHT11_GPIO_PORT,DHT11_GPIO_PIN)
extern DHT11_Data_TypeDef DHT11_Data;
void DHT11_Init( void );
uint8_t DHT11_Read_TempAndHumidity(DHT11_Data_TypeDef * DHT11_Data);
uint8_t DHT11_GetFlag();
void DHT11_GetVlaue(DHT11_Data_TypeDef *DHT11_Data);
uint8_t DHT11_Tick(DHT11_Data_TypeDef *DHT11_Data);
#endif
使用说明
带阻塞读取 main.c
int main(void)
{
Serial_Init();
DHT11_Init();
while (1)
{
DHT11_Read_TempAndHumidity(&DHT11_Data);
Serial_Printf("当前温度:%.1f,当前湿度:%.1f\r\n",DHT11_Data.temperature,DHT11_Data.humidity);
Delay_ms(1000);
}
}
无阻塞读取 main.c
int main(void)
{
MY_Tim2_Init(10,72); //10us
Serial_Init();
DHT11_Init();
while (1)
{
if(DHT11_GetFlag() == 1)
{
DHT11_GetVlaue(&DHT11_Data);
Serial_Printf("当前温度:%.1f,当前湿度:%.1f\r\n",DHT11_Data.temperature,DHT11_Data.humidity);
}
Delay_ms(1000);
}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
{
DHT11_Tick(&DHT11_Data);
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
}
注意事项
1. DHT11_Read_TempAndHumidity函数中的Delay延时函数一定要是系统定时器实现的精确延时,否则可能会读取不到数据。
2. DHT11_Tick函数需要每10us秒执行一次,可以放在定时器中断中实现。
作者声明
代码中有许多冗余的地方,欢迎各位指正修改。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)