DHT11溫濕度傳感器


硬件連接:

MCU通過一條數據線與DH11連接,MCU通過這條線發命令給DH11,DH11再通過這條線把數據發送給MCU。

 

溫濕度模塊的核心就是 MCU發給DH11的命令格式和DH11返回的數據格式。

時序:

 

首先MCU發送一個開始信號S,這個開始信號是一個低脈沖,然后再拉高。等待DHT11應答。

然后,DH11拉低,做出一個響應信號,再拉高,准備發送數據。

接着就是DH11返回的數據。

這些數據一共有40bit,高位先出。(8bit濕度整數數據+8bit濕度小數數據+8bi溫度整數數據+8bit溫度小數數據+8bit校驗和)

數據有40bit: 8bit濕度整數數據+8bit濕度小數數據+8bit溫度整數數據+8bit溫度小數數據+8bit校驗和

時序要求:

 

MCU必須先拉低至少18ms,然后再拉高20-40us,DH11再拉低80us以響應,最后再拉高80us.

接下來就是傳輸數據:

Bit01bit 50us開始后,DHT11拉低數據時間為30us以內

 Bit1:1bit 50us開始后,DHT11拉低數據時間為超過70us

代碼實現:

實現GPIO的基本操作:

GPG5,gpio配置如下:

 

 

static void dht11_data_cfg_as_output(void)
{
        GPGCON &= ~(3<<10);
        GPGCON |= (1<<10);
}
static void dht11_data_cfg_as_input(void)
{
        GPGCON &= ~(3<<10);
}

static void dht11_data_set(int val)
{
        if (val)
                GPGDAT |= (1<<5);
        else
                GPGDAT &= ~(1<<5);
}
static int dht11_data_get(void)
{
        if (GPGDAT & (1<<5))
                return 1;
        else
                return 0;
}
DHT11操作:
void dht11_init(void)
{
    dht11_data_cfg_as_output();
    dht11_data_set(1);
    mdelay(2000);
}

static void dht11_start(void)
{
    dht11_data_set(0);
    mdelay(20);
    dht11_data_cfg_as_input();
}

static int dht11_wait_ack(void)
{
    udelay(60);
    return dht11_data_get();
}

static int dht11_recv_byte(void)
{
    int i;
    int data = 0;
    
    for (i = 0; i < 8; i++)
    {
        if (dht11_wait_for_val(1, 1000))
        {
            printf("dht11 wait for high data err!\n\r");
            return -1;
        }
        udelay(40);
        data <<= 1;
        if (dht11_data_get() == 1)
            data |= 1;
        
        if (dht11_wait_for_val(0, 1000))
        {
            printf("dht11 wait for low data err!\n\r");
            return -1;
        }
    }
    
    return data;
}

static int dht11_wait_for_val(int val, int timeout_us)
{
    while (timeout_us--)
    {
        if (dht11_data_get() == val)
            return 0; /* ok */
        udelay(1);
    }
    return -1; /* err */
}


int dht11_read(int *hum, int *temp)
{
    unsigned char hum_m, hum_n;
    unsigned char temp_m, temp_n;
    unsigned char check;        
    
    dht11_start();
    
    if (0 != dht11_wait_ack())
    {
        printf("dht11 not ack, err!\n\r");
        return -1;
    }

    if (0 != dht11_wait_for_val(1, 1000))  /* 等待ACK變為高電平, 超時時間是1000us */
    {
        printf("dht11 wait for ack high err!\n\r");
        return -1;
    }

    if (0 != dht11_wait_for_val(0, 1000))  /* 數據階段: 等待低電平, 超時時間是1000us */
    {
        printf("dht11 wait for data low err!\n\r");
        return -1;
    }

    hum_m  = dht11_recv_byte();
    hum_n  = dht11_recv_byte();
    temp_m = dht11_recv_byte();
    temp_n = dht11_recv_byte();
    check  = dht11_recv_byte();

    dht11_data_cfg_as_output();
    dht11_data_set(1);

    if (hum_m + hum_n + temp_m + temp_n == check)
    {
        *hum  = hum_m;
        *temp = temp_m;
        mdelay(2000);  /* 讀取周期是2S, 不能讀太頻繁 */
        return 0;
    }
    else
    {
        printf("dht11 checksum err!\n\r");
        return -1;
    }

}

void dht11_test(void)
{
    int hum, temp;
    
    dht11_init();
    
    while (1)
    {
        if (dht11_read(&hum, &temp) !=0 )
        {
            printf("\n\rdht11 read err!\n\r");
            dht11_init();
        }
        else
        {
            printf("\n\rDHT11 : %d humidity, %d temperature\n\r", hum, temp);
        }
    }
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM