STM32F407 DHT11 数字温湿度传感器实验

1 DHT11 简介

        DHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC
测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够
实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一
个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式
进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大
电流 0.5mA。 
DHT11 的技术参数如下: 
⚫ 工作电压范围:3.3V-5.5V 
⚫ 工作电流 :平均 0.5mA 
⚫ 输出:单总线数字信号 
⚫ 测量范围:湿度 20~90%RH,温度 0~50℃ 
⚫ 精度 :湿度±5%,温度±2℃ 
⚫ 分辨率 :湿度 1%,温度 1℃ 
DHT11 的管脚排列如图 36.1.1 所示:

        DHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向
传输。其数据包由 5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数
数据+8bit 温度小数数据+8bit 校验和。其中校验和数据为前四个字节相加。 
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开
处理。例如,某次从 DHT11 读到的数据如图 36.1.2 所示:

计算方法: 
                湿度= byte4 . byte3=45.0 (%RH) 
                温度= byte2 . byte1=28.0 ( ℃) 
                校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确) 
        DHT11和 MCU的一次通信最大为 3ms 左右,建议主机连续读取时间间隔不要小于 100ms。 DHT11 的传输时序:

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

        DHT11 输出数字‘0’的时序:

DHT11 输出数字‘1’的时序:

部分代码:

//复位 DHT11 
void DHT11_Rst(void) 
{ 
    DHT11_IO_OUT(); //SET OUTPUT 
    DHT11_DQ_OUT=0; //拉低 DQ 
    delay_ms(20); //拉低至少 18ms 
    DHT11_DQ_OUT=1; //DQ=1 
    delay_us(30); //主机拉高 20~40us 
} 
//等待 DHT11 的回应 
//返回 1:未检测到 DHT11 的存在 
//返回 0:存在 
u8 DHT11_Check(void) 
{ 
    u8 retry=0; 
    DHT11_IO_IN();//SET INPUT 
    while (DHT11_DQ_IN&&retry<100)//DHT11 会拉低 40~80us 
    { 
        retry++;delay_us(1); 
    }; 
    if(retry>=100)return 1; 
    else retry=0; 
    while (!DHT11_DQ_IN&&retry<100)//DHT11 拉低后会再次拉高 40~80us 
    { 
        retry++;delay_us(1); 
    }; 
    if(retry>=100)return 1; 
        return 0; 
    } 
//从 DHT11 读取一个位 
//返回值:1/0 
u8 DHT11_Read_Bit(void) 
{ 
    u8 retry=0; 
    while(DHT11_DQ_IN&&retry<100)//等待变为低电平 
    { 
        retry++;delay_us(1); 
    } 
    retry=0; 
    while(!DHT11_DQ_IN&&retry<100)//等待变高电平 
    { 
        retry++;delay_us(1); 
    } 
    delay_us(40);//等待 40us 
    if(DHT11_DQ_IN)return 1; 
    else return 0; 
} 
//从 DHT11 读取一个字节 
//返回值:读到的数据 
u8 DHT11_Read_Byte(void) 
{ 
    u8 i,dat; 
    dat=0; 
    for (i=0;i<8;i++) 
    { 
         dat<<=1; 
         dat|=DHT11_Read_Bit(); 
     } 
     return dat; 
} 
//从 DHT11 读取一次数据 
//temp:温度值(范围:0~50°) 
//humi:湿度值(范围:20%~90%) 
//返回值:0,正常;1,读取失败 
u8 DHT11_Read_Data(u8 *temp,u8 *humi) 
{ 
     u8 buf[5],u8 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 1; 
 return 0; 
} 
//初始化 DHT11 的 IO 口 DQ 同时检测 DHT11 的存在 
//返回 1:不存在 
//返回 0:存在 
u8 DHT11_Init(void) 
{     
    GPIO_InitTypeDef GPIO_InitStructure; 
 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能 GPIOG 时钟 
 
    //GPIOF9,F10 初始化设置 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 
    GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化 
    DHT11_Rst(); 
    return DHT11_Check(); 
} 

主要是通过单总线操作时序来读取 DHT11 的温湿度值的,DHT11的温湿度值通过DHT11_Read_Data 函数读取,如果返回 0,则说明读取成功,返回 1,则说明读取失败。

  • 23
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值