目录
一、实物图&原理图
温度值:-20~60;湿度值:5~95
二、时序编写
//端口配置:GPIOA_PIN_8
GPIO_InitTypeDef GPIO_InitStruct = {0};
void Set_GPIO_Output_State(void)//通用推挽输出
{
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//通用推挽输出
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void Set_GPIO_Input_State(void)//浮空输入模式
{
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//输入
GPIO_InitStruct.Pull = GPIO_NOPULL ;//没有上拉或下拉激活,浮空输入模式
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void DHT11_Read(void)//主机发送起始信号
{
Set_GPIO_Output_State();//设置通用推挽输出
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);//主机起始信号至少拉低18ms
HAL_Delay(20);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);//主机释放总线时间至少10us
delay_us(13);
Set_GPIO_Input_State();//浮空输入模式
}
uint8_t dht11_check(void)//从机响应信号
{
uint8_t retry=0;
Set_GPIO_Input_State();//输入模式
while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)&&retry<100)//DHT11响应信号是高电平时
{//至少拉高85us
retry++;
delay_us(1);
};
if(retry>=100)return 1;//响应异常
else retry=0;/*响应正常清空计数***********************************************/
while (!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)&&retry<100)//DHT11响应信号是低电平时
{//至少拉低81us
retry++;
delay_us(1);
};
if(retry>=100)return 1;//响应异常
return 0;//响应正常
}
uint8_t dht11_read_bit(void)//数据传输
{
uint8_t retry=0;
while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)&&retry<100)
{
retry++;
delay_us(1);
}
retry=0;//清空计数
while(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8)&&retry<100)
{
retry++;
delay_us(1);
}
delay_us(40);//如果是高电平时延时40us
if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8))
{
return 1;//还是高电平则是数据1
}
else return 0;//低电平则是数据0
}
三、数据处理
法一
uint8_t DHT11_Read_Byte(void)//获取1字节数据
{
uint8_t mask,dat=0;
for(mask=0x80;mask!=0;mask>>=1)
{
if(dht11_read_bit()) dat|=mask;//数据1
else dat &=~mask; //数据0
}
return dat; //返回1字节数据
}
法二
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读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
uint8_t DHT11_Read_Data(uint8_t *humiH,uint8_t *humiL,uint8_t *tempH,uint8_t *tempL)
{
uint8_t buf[5]={0,};
DHT11_Read();//主机发送起始信号
if(dht11_check()==0)//从机响应信号
{
for(uint8_t i=0; i<5; i++) //读取40位数据
{
buf[i]=DHT11_Read_Byte();
}
if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
{
*humiH=buf[0];
*humiL=buf[1];
*tempH=buf[2];
*tempL=buf[3];
}
} else
{
return 1;//从机响应信号异常
}
return 0;
}