• 基于STM32的DHT11温湿度测量


    目录

    1.简介

    2.主要参数 

     3.引脚说明

    4.注意事项

    5.单总线协议

    6.数据格式

    7.工作时序

    8.分模块编写程序


    1.简介

      DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。DHT11实物图和内部框图如下图。
    DHT11
    DHT11内部框图
    DHT11内部框图

    2.主要参数 

    温湿度性能
    湿度量程5  -  95  %RH误差:±5%RH(25℃)
    湿度量程-20  -  60 ℃误差:±2℃(25℃)
    电气特性
    供电电压3.3 - 5.5单位:V
    供电电流
    0.06(待机) 、1.0(测量)   
    单位:mA
    采样周期>2单位:s

     3.引脚说明

    VDD
    供电3.3~5.5V DC
    DATA
    串行数据,单总线
    NC
    空脚
    GND
    接地,电源负极

    4.注意事项

    1、典型应用电路中建议连接线长度短于5m时用4.7K上拉电阻,大于5m时根据实际情况降
          低上拉电阻的阻值。
    2、使用3.3V电压供电时连接线尽量短,接线过长会导致传感器供电不足,造成测量偏差。
    3、每次读出的温湿度数值是上一次测量的结果,欲获取实时数据,需连续读取2次,但不
          建议连续多次读取传感器,每次读取传感器间隔大于2秒即可获得准确的数据。
    4、电源部分如有波动,会影响到温度。如使用开关电源,温度就会跳动。

    5.单总线协议

       DHT11器件采用单总线通信来实现数据交换和控制,这种通信方式只有一根数据线。设备可以通过漏极开路或三态端口连接到数据线上,以允许设备在不发送数据时释放总线并让其他设备使用。为了让总线保持高电平状态,通常需要外接一个约4.7kΩ的上拉电阻。由于DHT11器件采用主从结构,只有在主机呼叫从机时,从机才能作出响应。因此,主机访问DHT11器件时必须严格遵循单总线序列,否则器件将不会响应主机。

    6.数据格式

      DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次传送40位数据,高位先出。
    (1)数据格式:
    8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验位。
    注:其中湿度小数部分为0。
    (2)校验位数据定义:
    “8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据”8bit校验
    位等于所得结果的末8位。
    (3)校验:
    校验位=湿度高位+湿度低位+温度高位+温度低位

    7.工作时序

    首先主机发送开始信号,即:拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2(20~40us)时间,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间后,开始输出数据。

    8.分模块编写程序

    (1)IO方向设置和输出设置

    1. //IO方向设置
    2. #define DHT11_IO_IN() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8;}
    3. #define DHT11_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3;}
    4. //IO操作函数
    5. #define DHT11_DQ_OUT(x) {if(x==0) GPIO_ResetBits(GPIOA,GPIO_Pin_0); else if(x==1) GPIO_SetBits(GPIOA,GPIO_Pin_0);}//数据端口
    6. #define DHT11_DQ_IN GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //数据端口

    (2)STM32发出复位信号

    拉低数据线,保持t1(至少18ms)时间,然后拉高数据线t2 (20~40us)时间

    1. void DHT11_Rst(void)
    2. {
    3. DHT11_IO_OUT(); //SET OUTPUT
    4. DHT11_DQ_OUT(0); //拉低DQ 至少18ms
    5. delay_ms(20);
    6. DHT11_DQ_OUT(1); //主机拉高20~40us
    7. delay_us(30);
    8. }

    (3)等待DHT11回应(检测DHT11是否存在)

    DHT11会拉低数据线,保持t3(40~50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40~50us)时间

    1. u8 DHT11_Check(void)
    2. {
    3. u8 retry = 0;
    4. DHT11_IO_IN();//SET INPUT
    5. while(DHT11_DQ_IN && retry < 100) //DHT11会拉低40~80us(拉低会跳出while)
    6. {
    7. retry++;
    8. delay_us(1);
    9. }
    10. if(retry >= 100)
    11. return 1;
    12. else
    13. retry = 0;
    14. while(!DHT11_DQ_IN && retry < 100) //DHT11拉低后会再次拉高(DHT11_DQ_IN = 1)40~80us (!DHT11_DQ_IN 为0 跳出while 表示DHT11拉高)
    15. {
    16. retry++;
    17. delay_us(1);
    18. }
    19. if(retry >= 100)
    20. {
    21. return 1;
    22. }
    23. return 0;
    24. }

    (4)读一个位数据

    DHT11发送0时序

     首先12-14us的开始信号,然后是26-28us高电平(代表0)

    DHT11发送1时序

      首先12-14us的开始信号,然后是116-118us高电平(代表1)

    1. u8 DHT11_Read_Bit(void)
    2. {
    3. u8 retry = 0;
    4. while(DHT11_DQ_IN && retry < 100) //主机读时 DHT11会先拉低12~14us(拉低会跳出while)
    5. {
    6. retry++;
    7. delay_us(1);
    8. }
    9. if(retry >= 100)
    10. return 1;
    11. else
    12. retry = 0;
    13. while(!DHT11_DQ_IN && retry < 100) //主机读时 为0(再拉高26~28us) 为1(再拉高116~118us)
    14. {
    15. retry++;
    16. delay_us(1);
    17. }
    18. delay_us(40); //等40us 判断此时电位 高电平为1 低电平为0
    19. if(DHT11_DQ_IN)
    20. return 1;
    21. else
    22. return 0;
    23. }

    (5)读一个字节数据

    1. u8 DHT11_Read_Byte(void)
    2. {
    3. u8 i, dat;
    4. dat = 0;
    5. for (i = 0; i < 8; i++)
    6. {
    7. dat <<= 1;
    8. dat |= DHT11_Read_Bit();
    9. }
    10. return dat;
    11. }

    (6)一次性读取数据并校验

    1. u8 DHT11_Read_Data(u8 *temp, u8 *humi)
    2. {
    3. u8 buf[5];
    4. u8 i;
    5. DHT11_Rst();
    6. if(DHT11_Check() == 0) //温湿度传感器连接正常
    7. {
    8. for(i = 0; i < 5; i++)
    9. {
    10. buf[i] = DHT11_Read_Byte(); //5个字节读入buf数组
    11. }
    12. if((buf[0] + buf[1] + buf[2] + buf[3]) == buf[4])//校验 前四个字节和等于第五个字节
    13. {
    14. *humi = buf[0];
    15. *temp = buf[2];
    16. }
    17. }
    18. else
    19. return 1;
    20. return 0;
    21. }

    (7)初始化代码

    1. u8 DHT11_Init(void)
    2. {
    3. GPIO_InitTypeDef GPIO_InitStructure;
    4. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PC端口时钟
    5. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PC2端口配置
    6. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
    7. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    8. GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口
    9. GPIO_SetBits(GPIOA, GPIO_Pin_0); //PC2 输出高
    10. DHT11_Rst(); //复位DHT11
    11. return DHT11_Check();//等待DHT11的回应
    12. }

    说明:本文章部分内容参考 ASARI温湿度模块DHT11 产品手册

    以上就是DHT11的所有内容了,更多传感器驱动代码请订阅我的传感器专栏

  • 相关阅读:
    C++设计模式-外观模式,游戏引擎管理多个子系统,反汇编
    【前端】JavaScript
    统计子矩阵
    VLN阅读报告6:SOON: Scenario Oriented Object Navigation with Graph-based Exploration
    如何在SAP GUI中快速执行新的事务代码
    【LeetCode算法系列题解】第56~60题
    HashMap如何确定数组位置
    Dubbo应用与实践
    Spring注解中的@DependsOn是什么意思
    AI芯片技术-2022年
  • 原文地址:https://blog.csdn.net/weixin_46364710/article/details/130897555