傳感器系列 溫溼度傳感器DHt11

傳感器不是最近纔出來的產品,在工業領域,自動化控制領域和汽車領域,都很廣泛的應用。在大衆應用市場上比較少,
隨着物聯網的到來,傳感器技術會應用的越來越廣泛。 開始從溫溼度這快入手,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)  //數據端口   PG11


u8 DHT11_Init(void);//初始化DHT11
u8 DHT11_Read_Data(u8 *temp,u8 *humi);//讀取溫溼度
u8 DHT11_Read_Byte(void);//讀出一個字節
u8 DHT11_Read_Bit(void);//讀出一個位
u8 DHT11_Check(void);//檢測是否存在DHT11
void DHT11_Rst(void);//復位DHT11    
#endif

dht11.c代碼如下:

#include "dht11.h"
#include "delay.h"
//DHT11數字溫溼度傳感器驅動代碼    
//All rights reserved                                     

//復位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)
{
    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串口調試顯示當前的溫溼度如下:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章