【AT-START-F423测评】5.单数据线通讯读取DHT11温湿度

DHT11是一种数字温湿度传感器,使用一根数据线进行数据传输,要求IO既能输出又能输入,使用开漏输出模式正好能满足要求
开漏模式下GPIO可以真正输出低电平,输出高电平需要借助上拉电阻,当需要作为输入时,只需要程序内输出高电平,之后外设就可以控制电平高低了
 


在AT32 Work Bench中将PD8配置成开漏输出,DHT11已经内置了10K的上拉电阻,这里就不配置上拉了,默认输出高电平

 


实现GPIO的操作,开漏模式下可以通过读输入读取真实的电平

复制

#define YUYY_GPIO_LEV_TYPE flag_status

#define YUYY_GPIO_LEV1 SET

#define YUYY_GPIO_LEV0 RESET

void yuyy_gpio_setlev(YUYY_GPIO_DEV_t *gpio_dev,YUYY_GPIO_LEV_TYPE lev)

{

    gpio_bits_write(gpio_dev->gpio,gpio_dev->pin,lev);

}

YUYY_GPIO_LEV_TYPE yuyy_gpio_readlev(YUYY_GPIO_DEV_t *gpio_dev)

{

     return gpio_input_data_bit_read(gpio_dev->gpio,gpio_dev->pin);

}

void yuyy_gpio_opod_out(YUYY_GPIO_DEV_t *gpio_dev)

{

    

}

void yuyy_gpio_opod_in(YUYY_GPIO_DEV_t *gpio_dev)

{

    gpio_bits_write(gpio_dev->gpio,gpio_dev->pin,YUYY_GPIO_LEV1);

}

参考手册实现DHT11的通讯
 

复制

enum

{

    YUYY_DHT11_OK = 0,

    YUYY_DHT11_ERROR_DATIOBUSY,

    YUYY_DHT11_ERROR_NOACK,

    YUYY_DHT11_ERROR_ACKBLOCK,

    YUYY_DHT11_ERROR_READDATA,

    YUYY_DHT11_ERROR_DATACHECK

};

typedef struct

{

    YUYY_GPIO_DEV_t dat;

}YUYY_DHT11_DEV_t;

uint8_t yuyy_dht11_readHT(YUYY_DHT11_DEV_t *dht11_dev,float *tem,float *hum)

{

    uint8_t retry = 0,i=0,j=0,check=0;

    uint8_t buffer[5] = {0};

    yuyy_gpio_opod_out(&(dht11_dev->dat)); //输出模式

    yuyy_gpio_setlev(&(dht11_dev->dat),YUYY_GPIO_LEV0); //拉低

    yuyy_dht11_delay_ms(20);

    yuyy_gpio_opod_in(&(dht11_dev->dat)); //输入模式

    retry = 0;

    while  (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV0)

    {

        yuyy_dht11_delay_us(10);

        retry += 1;

        if(retry > 2)

            return YUYY_DHT11_ERROR_DATIOBUSY;

    }

    while (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV1)

    {

        yuyy_dht11_delay_us(10);

        retry += 1;

        if(retry > 20)

            return YUYY_DHT11_ERROR_NOACK;

    }

    retry = 0;

    while  (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV0)

    {

        yuyy_dht11_delay_us(10);

        retry += 1;

        if(retry > 9)

            return YUYY_DHT11_ERROR_ACKBLOCK;

    }

    retry = 0;

    while (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV1)

    {

        yuyy_dht11_delay_us(10);

        retry += 1;

        if(retry > 10)

            return YUYY_DHT11_ERROR_ACKBLOCK;

    }

    while(i<5)

    {

        j = 0;

        while (j < 8)

        {

            buffer[i] <<= 1;

            retry = 0;

            while (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV0)

            {

                yuyy_dht11_delay_us(10);

                retry += 1;

                if(retry > 6)

                    return YUYY_DHT11_ERROR_READDATA;

            }

            retry = 0;

            while (yuyy_gpio_readlev(&(dht11_dev->dat)) == YUYY_GPIO_LEV1)

            {

                yuyy_dht11_delay_us(10);

                retry += 1;

                if(retry > 8)

                    return YUYY_DHT11_ERROR_READDATA;

            }

            if(retry > 5)

                buffer[i] |= 0x01;

            j += 1;

        }

        if(i<4)

            check += buffer[i];

        i += 1;

    }

    if(check != buffer[4])

        return YUYY_DHT11_ERROR_DATACHECK;

    *hum = buffer[0];

    *tem = buffer[2];

    if((buffer[3] & 0x7F) < 10)

    {

        *tem += (buffer[3] & 0x7F)/10.0;

    }

    if((buffer[3] & 0x80) > 0)

        *tem = 0 - *tem;

    return YUYY_DHT11_OK;

}

使用printf打印温湿度

复制

YUYY_DHT11_DEV_t dht11_dev;

void dht11_init()

{

    dht11_dev.dat.gpio = DHT11_DAT_GPIO_PORT;

    dht11_dev.dat.pin = DHT11_DAT_PIN;

}



void dht11_readHT()

{

    float humi,temp;

    uint8_t result = yuyy_dht11_readHT(&dht11_dev,&temp,&humi);

    if(YUYY_DHT11_OK == result)

    {

        printf("DHT11 读取 温度:%.1f℃ 湿度:%.1f%%",temp,humi);

    }

    else

    {

        printf("DHT11 读取错误:%d",result);

    }

}

运行效果
 


结合之前的LCD屏幕,可以做个简单地温湿度监测器


---------------------
作者:yuyy1989
链接:https://bbs.21ic.com/icview-3336430-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值