基于物联网的远程温湿度监测系统(2)编写 DHT11 驱动

发布时间:2024-07-03  

前言

本项目主要通过使用STM32F103C8T6作为主控MCU,ESP8266作为数据透传模块,接入机智云AIoT云平台,通过在线智能产品,实现了远程联网、温湿度监测、APP控制等功能。


在上文中,主要介绍了“创建云端产品,烧录Gagent”,以便让设备能够联网,当然其中也备注了ESP8266烧写Gagent固件时的注意事项,说明定义数据点的作用。


在本文中,从原理开始讲解,阐述DHT11驱动的编写。


进入正文

1、DHT11 简要介绍

DHT11 器件采用简化的单总线通信,DATA 引脚用于微处理器与 DHT11 之间的通讯和同步,一次传送 40 位数据,高位先出。

69ce4e64-c3ef-11ec-8521-dac502259ad0.png



举例:

69ed654c-c3ef-11ec-8521-dac502259ad0.png


2、时序分析(附代码)

用户主机(MCU)发送一次开始信号后,DHT11 从低功耗模式转换到高速模式,待主机开始信号结束后,DHT11 发送响应信号,送出 40bit 的数据,信号发送如图所示。

6a02e8e0-c3ef-11ec-8521-dac502259ad0.png

注意:主机(MCU)从 DHT11 读取的温湿度数据总是前一次的测量值。


总线空闲:

DHT11 的 DATA 数据线由上拉电阻拉高一直保持高电平,此时 DHT11 的DATA 引脚处于输入状态,时刻检测外部信号。


MCU 发出请求信号:

MCU I/O 设置为输出同时输出低电平,且低电平保持时间不能小于 18ms,然后MCU I/O设置为输入状态。由于上拉电阻,MCU I/O 即 DHT11 的 DATA 数据线也随之变高,之后等待 DHT11 作出回答信号。


DHT11 发出应答信号:

当 DHT11 的 DATA 引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA引脚处于输出状态,输出 80us的低电平作为应答信号,紧接着输出 80us 的高电平通知 MCU 准备接收数据,MCU I/O 此时处于输入状态,检测到 DHT11 回应信号后,等待 80us 的高电平后的数据接收。

6a17c288-c3ef-11ec-8521-dac502259ad0.png


MCU 接收 40 位数据

由 DHT11 的 DATA 引脚输出 40 位数据,MCU 根据 I/O 电平的变化来判断是 “0” 还是 “1” 。


位数据 “0” 的格式为:

50us 的低电平和 26-28us的高电平。

6a2ce62c-c3ef-11ec-8521-dac502259ad0.png


位数据 “1” 的格式为:

50us 的低电平加 70us 的高电平。

6a4ba6e8-c3ef-11ec-8521-dac502259ad0.png

DHT11 发出结束信号

DHT11 的 DATA 引脚输出 40 位数据后,继续输出低电平 50us 后转为输入状态,由于上拉电阻存在,变为高电平。


    // 本驱动采用 HAL 库,us 级延时使用通用定时器实现,对 IO 引脚的状态的改变采用位操作以及直接寄存器操作


    // 复位DHT11

    void DHT11_Rst(void)

    {                 

        DHT11_IO_OUT();   //设置为输出

      DHT11_DQ_OUT = 0;   //拉低

      HAL_Delay_ms(20);   //拉低至少18ms

      DHT11_DQ_OUT = 1;   //拉高 

      HAL_Delay_us(30);   //主机拉高20~40us

    }


    //等待DHT11的回应

    //返回1:未检测到DHT11的存在

    //返回0:存在

    uint8_t DHT11_Check(void)      

    {   

    uint8_t retry = 0;

      DHT11_IO_IN();      //设置为输入   

    while(DHT11_DQ_IN && retry < 100)  //DHT11会拉低40~80us

      {

        retry++;

        HAL_Delay_us(1);

      }   

    if(retry >= 100)

    return 1;

    else

        retry = 0;


    while(!DHT11_DQ_IN && retry < 100)  //DHT11拉低后会再次拉高40~80us

      {

        retry++;

        HAL_Delay_us(1);

      }

    if(retry >= 100)

    return 1;      

    return 0;

    }


    //从DHT11读取一个位

    //返回值:1/0

    uint8_t DHT11_Read_Bit(void)        

    {

    uint8_t retry = 0;

    while(DHT11_DQ_IN && retry < 100)//等待变为低电平

      {

        retry++;

        HAL_Delay_us(1);

      }

      retry = 0;

    while(!DHT11_DQ_IN && retry < 100)//等待变高电平

      {

        retry++;

        HAL_Delay_us(1);

      }

      delay_us(40);//等待40us

    if(DHT11_DQ_IN)

    return 1;

    else

    return 0;       

    }


    //从DHT11读取一个字节

    //返回值:读到的数据

    uint8_t DHT11_Read_Byte(void)    

    {        

    uint8_t i,dat;

      dat = 0;

    for (i=0;i<8;i++) 

      {

          dat <<= 1; 

          dat |= DHT11_Read_Bit();

      }                

    return dat;

    }


    //从DHT11读取一次数据

    //temp0~50°)

    //humi20%~90%)

    //返回值:0,正常;1,读取失败;2,校验和错误

    uint8_t DHT11_Read_Data(uint8_t *temp, uint8_t *humi)    

    {        

    uint8_t buf[5];

    uint8_t i;

      DHT11_Rst();

    if(DHT11_Check() == 0)

      {

    for(i = 0; i < 5; i++)   //读取40位数据

        {

          buf[i] = DHT11_Read_Byte();

        }

    if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])

        {

          *humi = buf[0];  

          *temp = buf[2];

        }

    else

    return 2;  // 校验和错误

      }

    else

    return 1;

    return 0;      

    }


    //初始化DHT11的 IO口, 同时检测DHT11的存在

    //返回1:不存在

    //返回0:存在        

    uint8_t DHT11_Init(void)

    {

      DHT11_GPIO_Init();


      DHT11_Rst();

    return DHT11_Check();

    }


    3、使用串口观察数据


    将 printf 函数重定向至与 PC 相连的串口上。由于重定向相关函数已经包含在机智云生成的代码中(gizwits_product.c),我们直接使用 printf 进行数据打印即可。


    #ifdef __GNUC__

    /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf

         set to 'Yes') calls __io_putchar() */

    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

    #else

    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

    #endif /* __GNUC__ */

    /**

      * @brief  Retargets the C library printf function to the USART.

      * @param  None

      * @retval None

      */

    PUTCHAR_PROTOTYPE

    {

    /* Place your implementation of fputc here */

    /* e.g. write a character to the USART1 and Loop until the end of transmission */

      HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);


    return ch;

    }


    以下为相关测试代码:


    state = DHT11_Read_Data(&temperature, &humidity);

    if(state == 2)

    {

    printf("the checksum is errorn");

    }

    else if(!state)

    {

    printf("temp = %d , humi = %dn", temperature, humidity);

    }

    else

    {

    printf("DHT11 is not answern");

    }


    若采集到的数据没有问题,即可将机智云协议相关代码移植进工程中。


    本文结束。


    文章来源于:电子工程世界    原文链接
    本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

    我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

    利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

    充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

    我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

    我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

    凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

    我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>