传感器系列 温湿度传感器DHt11

来源:互联网 发布:mac装机必备软件 2017 编辑:程序博客网 时间:2024/04/29 10:11

传感器不是最近才出来的产品,在工业领域,自动化控制领域和汽车领域,都很广泛的应用。在大众应用市场上比较少,
随着物联网的到来,传感器技术会应用的越来越广泛。 开始从温湿度这快入手,DHT11。一款湿温度一体化的数字传
感器,包括一个电阻式测湿元件和一个 NTC 测温元件。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要
一个I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式进行校验,有效的保
证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大电流 0.5mA。
性能指标 和特性如下:
工作电压范围:3.5V-5.5V
工作电流 :平均 0.5mA
湿度测量范围:20-90%RH
温度测量范围:0-50℃
湿度分辨率 :1%RH 8 位
温度分辨率 :1℃ 8 位
采样周期 :1S
单总线结构
与 TTL 兼容(5V)
实物图如下:
这里写图片描述
DHT11 数据结构
DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输
入输出双向传输。其数据包由5Byte(40Bit)组成。数据分小数部分和整数部分,具
体格式在下面说明。
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和
校验和数据为前四个字节相加。
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。
如果,某次从传感器中读取如下5Byte数据:
byte4 byte3 byte2 byte1 byte0
00101101 00000000 00011100 00000000 01001001
整数 小数 整数 小数* 校验和
湿度 温度 校验和
由以上数据就可得到湿度和温度的值,计算方法:
humi (湿度)= byte4 . byte3=45.0 (%RH)
temp (温度)= byte2 . byte1=28.0 ( ℃)
jiaoyan(校验)= byte4+ byte3+ byte2+ byte1=73(=humi+temp)(校验正确)

DHT11 的传输时序
DHT11 开始发送数据流程
这里写图片描述
主机发送开始信号后,延时等待 20us-40us 后读取 DH11T 的回应信号,读取总线为低电平,说明 DHT11 发送响
应信号,DHT11 发送响应信号后,再把总线拉高,准备发送数据,每一 bit 数据都以低电平开始,格式见下面图示。
如果读取响应信号为高电平,则 DHT11 没有响应,请检查线路是否连接正常。
主机复位信号和 DHT11 响应信号
这里写图片描述
数字‘0’信号表示方法
这里写图片描述
数字‘1’信号表示方法
这里写图片描述
软件的实现就直接使用下面代码
dht11.h 代码如下:

#ifndef __DHT11_H#define __DHT11_H #include "sys.h"   //All rights reserved                                     //IO方向设置#define DHT11_IO_IN()  {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}#define DHT11_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}////IO操作函数                                             #define DHT11_DQ_OUT PGout(11) //数据端口   PG11 #define DHT11_DQ_IN  PGin(11)  //数据端口   PG11u8 DHT11_Init(void);//初始化DHT11u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度u8 DHT11_Read_Byte(void);//读出一个字节u8 DHT11_Read_Bit(void);//读出一个位u8 DHT11_Check(void);//检测是否存在DHT11void DHT11_Rst(void);//复位DHT11    #endif

dht11.c代码如下:

#include "dht11.h"#include "delay.h"//DHT11数字温湿度传感器驱动代码    //All rights reserved                                     //复位DHT11void 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/0u8 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){    RCC->APB2ENR|=1<<8;    //使能PORTG口时钟     GPIOG->CRH&=0XFFFF0FFF;//PORTG.11 推挽输出    GPIOG->CRH|=0X00003000;    GPIOG->ODR|=1<<11;      //输出1                       DHT11_Rst();    return DHT11_Check();}

main.c 如下

#include "sys.h"#include "usart.h"      #include "delay.h"  #include "led.h" #include "dht11.h"   int main(void){               u16 t;    u16 len;        u16 times=0;        u8 temperature;             u8 humidity;                     Stm32_Clock_Init(9);    //系统时钟设置    uart_init(72,9600);     //串口初始化为9600    delay_init(72);         //延时初始化     LED_Init();             //初始化与LED连接的硬件接口    DHT11_Init();           //初始化与DHT11连接的硬件接口    while(1)    {        if(USART_RX_STA&0x8000)        {                   len=USART_RX_STA&0x3FFF;//得到此次接收到的数据长度            printf("\r\n您发送的消息为:\r\n\r\n");               for(t=0;t<len;t++)            {                USART1->DR=USART_RX_BUF[t];                while((USART1->SR&0X40)==0);//等待发送结束            }            printf("\r\n\r\n");//插入换行            USART_RX_STA=0;        }else        {            times++;            if(times%5000==0)            {                printf("\r\n 温湿度\r\n");            }            if(times%100==0)            {                LED0=!LED0;//闪烁LED,提示系统正在运行.                //BEEP=!BEEP;                DHT11_Read_Data(&temperature,&humidity);        //读取温湿度值                    printf("\r\n temperature = %d humidity = %d\r\n ",temperature,humidity);                    delay_ms(100);                   LED1=!LED1;                delay_ms(10);               }        }    }    }

通过stm32串口调试显示当前的温湿度如下:
这里写图片描述

1 0