RT-thread DHT11获取温湿度

基于正点原子STM32F1 安装RT-Thread固件库

点击进入Git Hub下载例程https://github.com/RT-Thread/rt-thread/

找到keil工程,并打开,沿以下路径

RT-thread\demo\demo-dht11\bsp\stm32\stm32f103-atk-warshipv3

在这里插入图片描述
打开,开始编程

创建一个dht11.c

#include "drv_dht11.h"
#include <rtdevice.h>
#include <rthw.h>
#include "sensor.h"
#include "board.h"
#include <stdint.h>
#include <rtdbg.h>

编写模块驱动

#ifndef rt_hw_us_delay
RT_WEAK void rt_hw_us_delay(rt_uint32_t us)
{
    rt_uint32_t delta;

    us = us * (SysTick->LOAD / (1000000 / RT_TICK_PER_SECOND));
    delta = SysTick->VAL;

    while (delta - SysTick->VAL < us) continue;
}
#endif

//复位DHT11
static void DHT11_Rst(rt_base_t pin)
{
	rt_pin_mode(pin,PIN_MODE_OUTPUT);   //SET OUTPUT
	rt_pin_write(pin, PIN_LOW);		//拉低DQ
	rt_thread_mdelay(20);		//拉低至少18ms
	
	rt_pin_write(pin, PIN_HIGH);		//DQ=1 
	rt_hw_us_delay(30);		//主机拉高20~40us

}

//等待DHT11的回应
//返回1:未检测到DHT11的存在
//返回0:存在
static uint8_t DHT11_Check(rt_base_t pin)
{
	uint8_t retry = 0;
	rt_pin_mode(pin,PIN_MODE_INPUT);   //SET INPUT
	while (rt_pin_read(pin) && retry < 100)//DHT11会拉低40~80us
	{
			retry++;
			rt_hw_us_delay(1);
	};

    if(retry >= 100)
        return 1;
    else
        retry = CONNECT_FAILED;

    while (!rt_pin_read(pin) && retry < 100)//DHT11拉低后会再次拉高40~80us
    {
        retry++;
        rt_hw_us_delay(1);
    };

    if(retry >= 100)
        return CONNECT_FAILED;

    return CONNECT_SUCCESS;
	
}



//从DHT11读取一个位
//返回值:1/0
static uint8_t DHT11_Read_Bit(rt_base_t pin)
{
	uint8_t retry = 0;
	while (rt_pin_read(pin) && retry < 100)//等待变为低电平
	{
			retry++;
			rt_hw_us_delay(1);
	}
	retry=0;
	while (!rt_pin_read(pin) && retry < 100)//等待变高电平
	{
			retry++;
			rt_hw_us_delay(1);
	}
	rt_hw_us_delay(40);//等待40us
	if(rt_pin_read(pin)) return 1;
	else return 0;
}

//从DHT11读取一个字节
//返回值:读到的数据
static uint8_t DHT11_Read_Byte(rt_base_t pin)
{
	uint8_t i,dat;
   dat=0;
	for (i=0;i<8;i++) 
	{
   		dat<<=1; 
	    dat|=DHT11_Read_Bit(pin);
  }						    
  return dat;
	

}

//从DHT11读取一次数据
//temp:温度值(范围:0~50°)
//humi:湿度值(范围:20%~90%)
//返回值:0,正常;1,读取失败
static uint8_t DHT11_Read_Data(rt_base_t pin,uint8_t *temp,uint8_t *humi)
{
  uint8_t i, buf[5];
	DHT11_Rst(pin);

	if(DHT11_Check(pin) == 0)
	{
		for(i=0; i<5; i++) /* read 40 bits */
		{
			buf[i] = DHT11_Read_Byte(pin);
		}

		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:存在   
static uint8_t DHT11_Init(rt_base_t pin)
{
//	DHT11_Rst(pin);  //复位DHT11
//	return DHT11_Check(pin);//等待DHT11的回应
	uint8_t ret = 0;

	DHT11_Rst(pin);
	
	ret = DHT11_Check(pin);
	if (ret != 0)
	{
			DHT11_Rst(pin);
			ret = DHT11_Check(pin);
	}

	return ret;
}


int32_t dht11_get_temperature(rt_base_t pin)
{
    static int32_t temOLD = 0;
    uint8_t humi=0, temp = 0;
    int32_t temNEW;

    DHT11_Read_Data(pin, &temp, &humi);

    temNEW = (humi << 16)|(temp<<0);

    if((temNEW != temOLD) && (temNEW !=0))
    {
        temOLD = temNEW;
    }
    return temOLD;
}

对接SENSOR框架

static rt_size_t _dht11_polling_get_data(rt_sensor_t sensor, struct rt_sensor_data *data)
{
    rt_int32_t temperature_humidity;
    if (sensor->info.type == RT_SENSOR_CLASS_TEMP)
    {
        temperature_humidity = dht11_get_temperature((rt_base_t)sensor->config.intf.user_data);
        data->data.temp = temperature_humidity;
        data->timestamp = rt_sensor_get_ts();
    }    
    return 1;
}

static rt_size_t dht11_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len)
{
    RT_ASSERT(buf);

    if (sensor->config.mode == RT_SENSOR_MODE_POLLING)
    {
        return _dht11_polling_get_data(sensor, buf);
    }
    else
        return 0;
}

static rt_err_t dht11_control(struct rt_sensor_device *sensor, int cmd, void *args)
{
    rt_err_t result = RT_EOK;

    return result;
}

static struct rt_sensor_ops sensor_ops =
{
    dht11_fetch_data,
    dht11_control
};


int rt_hw_dht11_init(const char *name, struct rt_sensor_config *cfg)
{
    rt_int8_t result;
    rt_sensor_t sensor_temp = RT_NULL; 
    
    if (!DHT11_Init((rt_base_t)cfg->intf.user_data))
    {
        /* temperature sensor register */
        sensor_temp = rt_calloc(1, sizeof(struct rt_sensor_device));
        if (sensor_temp == RT_NULL)
            return -1;

        sensor_temp->info.type       = RT_SENSOR_CLASS_TEMP;
        sensor_temp->info.vendor     = RT_SENSOR_VENDOR_DALLAS;
        sensor_temp->info.model      = "temp_dht11";
        sensor_temp->info.unit       = RT_SENSOR_UNIT_DCELSIUS;
        sensor_temp->info.intf_type  = RT_SENSOR_INTF_ONEWIRE;
        sensor_temp->info.range_max  = 50;
        sensor_temp->info.range_min  = 0;
        sensor_temp->info.period_min = 5;

        rt_memcpy(&sensor_temp->config, cfg, sizeof(struct rt_sensor_config));
        sensor_temp->ops = &sensor_ops;

        result = rt_hw_sensor_register(sensor_temp, name, RT_DEVICE_FLAG_RDONLY, RT_NULL);
        if (result != RT_EOK)
        {
            LOG_E("device register err code: %d", result);
            goto __exit;
        }

    }
    return RT_EOK;
    
__exit:
    if (sensor_temp)
        rt_free(sensor_temp);
    return -RT_ERROR;     
}

创建一个dht11.h文件

#ifndef _DHT11_H_
#define _DHT11_H_


#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "sensor.h"

#define CONNECT_SUCCESS  0
#define CONNECT_FAILED   1

struct dht11_device
{
    rt_base_t pin;
    rt_mutex_t lock;
};
typedef struct dht11_device *dht11_device_t;


int rt_hw_dht11_init(const char *name, struct rt_sensor_config *cfg);
uint8_t DHT11_Init(rt_base_t pin);
int32_t dht11_get_temperature(rt_base_t pin);

#endif

主程序main.c

创建线程

int main(void)
{
    rt_thread_t dht11_thread, led_thread;
    
    dht11_thread = rt_thread_create("dht11tem", read_temp_entry, "temp_dht11",
                                      640, RT_THREAD_PRIORITY_MAX / 2, 20);
    if (dht11_thread != RT_NULL)
    {
        rt_thread_startup(dht11_thread);
    }
    
    led_thread = rt_thread_create("ledshine", led_shine_entry, RT_NULL,
                                  192, RT_THREAD_PRIORITY_MAX / 2, 20);
    if (led_thread != RT_NULL)
    {
        rt_thread_startup(led_thread);
    }
    
    return RT_EOK;
}

创建相应的线程入口函数
模块温湿度获取

#define DHT11_DATA_PIN GET_PIN(B, 12)

static void read_temp_entry(void *parameter)
{
    rt_device_t dev = RT_NULL;
    struct rt_sensor_data sensor_data;
    rt_size_t res;

    dev = rt_device_find(parameter);
    if (dev == RT_NULL)
    {
        rt_kprintf("Can't find device:%s\n", parameter);
        return;
    }

    if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
    {
        rt_kprintf("open device failed!\n");
        return;
    }
    rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100);

    while (1)
    {
        res = rt_device_read(dev, 0, &sensor_data, 1);
        if (res != 1)
        {
            rt_kprintf("read data failed!size is %d\n", res);
            rt_device_close(dev);
            return;
        }
        else
        {
            if (sensor_data.data.temp >= 0)
            {

							uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0;      // get temp
              uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi
							rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
            }
        }
        rt_thread_mdelay(100);
    }
}

系统运行指示灯

/* defined the LED0 pin: PB5 */
#define LED0_PIN    GET_PIN(B, 5)
/* defined the LED1 pin: PE5 */
#define LED1_PIN    GET_PIN(E, 5)

static void led_shine_entry(void *parameter)
{
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);
    
    while(1)
    {
        rt_pin_write(LED0_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
        rt_pin_write(LED0_PIN, PIN_LOW);
        rt_thread_mdelay(500);
    }
}

最后

static int rt_hw_dht11_port(void)
{
    struct rt_sensor_config cfg;
    
    cfg.intf.user_data = (void *)DHT11_DATA_PIN;
    rt_hw_dht11_init("dht11", &cfg);
    
    return RT_EOK;
}
INIT_ENV_EXPORT(rt_hw_dht11_port);
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。首先,需要明确一下你的问题:你想知道如何使用 RT-Thread Studio,RT-Thread+ stm32f103c8最小系统板、DHT11温湿度模块、ESP01S模块控制LED灯并将数据发布和订阅到私有云IP的物联网系统程序是吗? 如果是这样,那么我可以给你提供一些基本的步骤和思路。首先,你需要了解 RT-Thread Studio 的基本操作和使用方法。RT-Thread Studio 是一个基于 Eclipse 的集成开发环境,它可以帮助你快速开发嵌入式系统。 接下来,你需要准备一些硬件设备,包括 stm32f103c8最小系统板、DHT11温湿度模块、ESP01S模块和LED灯。这些设备可以通过串口、I2C、SPI等接口与 stm32f103c8最小系统板相连。 然后,你需要编写一些程序代码,使用 RT-Thread 操作系统来控制这些设备。你可以使用 C 语言或者其他支持的编程语言来编写程序代码。需要注意的是,在编写程序代码之前,你需要了解 RT-Thread 操作系统的基本原理和使用方法。 最后,你需要将数据发布和订阅到私有云IP。这可以通过使用 MQTT 协议来实现。你需要使用 ESP01S模块来连接 WiFi 网络,并使用 MQTT 协议来将数据发布和订阅到私有云IP。需要注意的是,在使用 MQTT 协议之前,你需要了解其基本原理和使用方法。 总结一下,实现物联网系统需要掌握 RT-Thread Studio、RT-Thread 操作系统、硬件设备、编程语言和 MQTT 协议等知识。如果你对这些知识不熟悉,建议你先进行学习和研究,然后再开始实现物联网系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值