提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

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(&,&,&,&,&);然后打印就可以了。

2.USART串口打印

代码如下(示例):

//发送一个字节
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

都是时序配置问题。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐