• 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
  • 相关阅读:
    如何快速查看archlinux pacman 软件记录?
    如何快速判断检查主机ip端口是否存活?
    如何在不清楚有哪些tag的情况下拉取docker镜像?
    如何使用docker版Openresty测试框架Test::Nginx进行测试?
    .net mvc4 使用 System.Web.Optimization 对javascript和style的引入、代码合并和压缩的优化(ScriptBundle,StyleBundle,Bund
    zen coding de 一些快捷功能
    C# Xpath
    一个SQL SERVER查询分析器非常好用的工具
    探索MSSQL执行计划
    博客园武林人士
  • 原文地址:https://www.cnblogs.com/fuzidage/p/16148363.html
Copyright © 2020-2023  润新知