DHT11传感器的使用
DHT11的配置需要看厂家给的时序图,并不是复制粘贴就能使用的,一定是需要检查写的时序逻辑是否正确,才能正确的把湿度和温度读出。DHT11模块还是用的蛮多的,一个重要的传感器,学会看传感器时序图很重要,大部分时候bug都是时序配置问题。
·
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
DHT11的配置需要看厂家给的时序图,并不是复制粘贴就能使用的,一定是需要检查写的时序逻辑是否正确,才能正确的把湿度和温度读出。
一、DHT11时序图

8bitSDZ+8bitSDX+8bitWDZ+8bitWDX=8bit Check_Sum

时序很重要 时序很重要 时序很重要
测不出来多半是时序问题
二、使用步骤
1.DHT11的初始化
代码如下(示例):
void DHT11_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// 启用 GPIOB 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置 DHT11 引脚为推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void DHT11_Start(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
Delay_ms(20);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
Delay_us(30);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
uint8_t DHT11_Check(void)
{
uint8_t timeout =100;
DHT11_Start();
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == SET && timeout--)
if(timeout==0)
return 1;
timeout=100;
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == RESET && timeout--)
if(timeout==0)
return 1;
return 0;
}
uint8_t DHT11_ReadByte(void)
{
uint8_t i=0;
uint8_t Byte=0;
for(i=0;i<8;i++)
{
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == SET );
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == RESET);
Delay_us(40);
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == SET)
{
Byte |=(1<<(7-i));
}
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == SET);
}
return Byte;
}
void DHT11_Read(uint8_t *humidity_integral,uint8_t*humidity_decimal,uint8_t*temperature_integral,uint8_t*temperature_decimal,uint8_t*checksum) {
uint8_t i=0;
uint8_t buffer[5];
if (DHT11_Check() == 0) {
for(i=0;i<5;i++)
{
buffer[i] = DHT11_ReadByte();
}
if(buffer[0]+buffer[1]+buffer[2]+buffer[3]==buffer[4])
{
*humidity_integral = buffer[0];
*humidity_decimal = buffer[1];
*temperature_integral = buffer[2];
*temperature_decimal =buffer[3];
*checksum = buffer[4];
}
//这里可以标志位检测你是否写对代码逻辑可以通过点灯、串口、led显示来调试你的代码
else
{
}
}
}
读取到的温湿度通过函数返回回去,定义5个变量,把DHT11_Read(&,&,&,&,&);然后打印就可以了。
代码如下(示例):
//发送一个字节 void Serial_SendByte(uint8_t Byte) { USART_SendData(USART1,Byte); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } //发送一串数字 void Serial_SendArrary(uint16_t *Arrary,uint16_t length) { uint16_t i=0; for(i=0;i<length;i++) { Serial_SendByte(Arrary[i]); } } //发送一串字符串 void Serial_SendString(char *string) { while(*string!='\0') { Serial_SendByte(*string); string++; } } //发送一个数字 uint32_t Serial_Pow(uint32_t X,uint32_t Y) { uint32_t Result = 1; while(Y--) { Result *= X; } return Result; } void Serial_SendNum(uint32_t Number,uint32_t Length) { uint8_t i=0; for(i=0;i<Length;i++) { Serial_SendByte(Number /Serial_Pow(10,Length-i-1) % 10+0x30); } } //重定向函数还是挺有意思的,真的很猛,学会这个前面代码可以不用直接搓了, 上prtintf猛猛打印就可以了。 //利用printf函数打印到串口 int fputc(int ch,FILE *f) { Serial_SendByte(ch); return ch; } //可变参数的用法 就可以显示中文 void Serial_Printf(char *format, ...) { char string[100]; va_list arg; va_start(arg,format); vsprintf(string,format,arg); va_end(arg); Serial_SendString(string); }
总结
DHT11模块还是用的蛮多的,一个重要的传感器,学会看传感器时序图很重要,大部分时候bug
都是时序配置问题。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)