使用RT

一、准备

本篇文章主要介绍使用RT-Thread Studio 和瑞萨 CPK-RA2L1评估板,使用大佬的轮子采集温湿度

二、硬件准备

CPK-RA2L1评估板, 这个板子的芯片型号是 R7FA2L1AB2DFM,DHT11 温湿度传感器。

三、新建工程

1、总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。

2、总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态

3、数字0信号

4、数字1信号

四、驱动代码

/*

Copyright (c) 2006-2021, RT-Thread Development TeamSPDX-License-Identifier: Apache-2.0Change Logs:Date Author Notes2023-03-01 DYC the first version

/

#include “dht11.h”

#include

#include “hal_data.h”

#include

#define DBG_TAG “sensor.asair.dhtxx”

#ifdef PKG_USING_DHTXX_DEBUG

#define DBG_LVL DBG_LOG

#else

#define DBG_LVL DBG_ERROR

#endif

#include

/ timing /

#define DHT1x_BEGIN_TIME 20 / ms /

#define DHT2x_BEGIN_TIME 1 / ms /

#define DHTxx_PULL_TIME 30 / us /

#define DHTxx_REPLY_TIME 100 / us /

#define MEASURE_TIME 40 / us /

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;

}

/ *This function will split a number into two part according to times.@param num the number will be split@param integer the integer part@param decimal the decimal part@param times how many times of the real number (you should use 10 in this case)@return 0 if num is positive, 1 if num is negative

*/

int split_int(const int num, int *integer, int *decimal, const rt_uint32_t times)

{

int flag = 0;

if (num < 0) flag = 1;

int anum = num<0 ? -num : num;

integer = anum / times;

decimal = anum % times;

return flag;

}

/This function will convert temperature in degree Celsius to Kelvin.@param c the temperature indicated by degree Celsius@return the result

/

float convert_c2k(float c)

{

return c + 273.15;

}

/ *This function will convert temperature in degree Celsius to Fahrenheit.@param c the temperature indicated by degree Celsius@return the result

/

float convert_c2f(float c)

{

return c * 1.8 + 32;

}

/ *This function will convert temperature in degree Fahrenheit to Celsius.@param f the temperature indicated by degree Fahrenheit@return the result

/

float convert_f2c(float f)

{

return (f – 32) * 0.55555;

}

/ *This function will read a bit from sensor.@param pin the pin of Dout@return the bit value

/

static uint8_t dht_read_bit(const rt_base_t pin)

{

uint8_t retry = 0;

while(rt_pin_read(pin) && retry < DHTxx_REPLY_TIME)

{

retry++;

rt_hw_us_delay(1);

}

retry = 0;

while(!rt_pin_read(pin) && retry < DHTxx_REPLY_TIME)

{

retry++;

rt_hw_us_delay(1);

}

rt_hw_us_delay(MEASURE_TIME);

return rt_pin_read(pin);

}

/ *This function will read a byte from sensor.@param pin the pin of Dout@return the byte

*/

static uint8_t dht_read_byte(const rt_base_t pin)

{

uint8_t i, byte = 0;

for(i=0; i<8; i++)

{

byte <<= 1;

byte |= dht_read_bit(pin);

}

return byte;

}

/**This function will read and update data array.@param dev the device to be operated@return RT_TRUE if read successfully, otherwise return RT_FALSE.

/

rt_bool_t dht_read(dht_device_t dev)

{

RT_ASSERT(dev);

uint8_t i, retry = 0, sum = 0;

#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

rt_base_t level;

#endif

/ Reset data buffer /

rt_memset(dev->data, 0, DHT_DATA_SIZE);

/ MCU request sampling /

rt_pin_mode(dev->pin, PIN_MODE_OUTPUT);

rt_pin_write(dev->pin, PIN_LOW);

if (dev->type == DHT11) {

rt_thread_mdelay(DHT1x_BEGIN_TIME); / Tbe /

} else {

rt_thread_mdelay(DHT2x_BEGIN_TIME);

}

#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

level = rt_hw_interrupt_disable();

#endif

rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);

rt_hw_us_delay(DHTxx_PULL_TIME); / Tgo /

/ Waiting for sensor reply /

while (rt_pin_read(dev->pin) && retry < DHTxx_REPLY_TIME)

{

retry++;

rt_hw_us_delay(1); / Trel /

}

if(retry >= DHTxx_REPLY_TIME) return RT_FALSE;

retry = 0;

while (!rt_pin_read(dev->pin) && retry < DHTxx_REPLY_TIME)

{

retry++;

rt_hw_us_delay(1); / Treh /

};

if(retry >= DHTxx_REPLY_TIME) return RT_FALSE;

/ Read data /

for(i=0; i {

dev->data[i] = dht_read_byte(dev->pin);

}

#ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE

rt_hw_interrupt_enable(level);

#endif

/ Checksum */

for(i=0; i {

sum += dev->data[i];

}

if(sum != dev->data[4]) return RT_FALSE;

return RT_TRUE;

}

/**This function will get the humidity from dhtxx sensor.@param dev the device to be operated@return the humidity value

/

rt_int32_t dht_get_humidity(dht_device_t const dev)

{

RT_ASSERT(dev);

rt_int32_t humi = 0;

switch(dev->type)

{

case DHT11:

humi = dev->data[0] * 10 + dev->data[1];

break;

default:

break;

}

return humi;

}

/ *This function will get the temperature from dhtxx sensor.@param dev the device to be operated@return the temperature value

/

rt_int32_t dht_get_temperature(dht_device_t const dev)

{

RT_ASSERT(dev);

rt_int32_t temp = 0;

switch(dev->type)

{

case DHT11:

temp = dev->data[2] * 10 + (dev->data[3] & 0x7f);

if(dev->data[3] & 0x80) {

temp = -temp;

}

break;

default:

break;

}

return temp;

}

/ *This function will init dhtxx sensor device.@param dev the device to init@param pin the pin of Dout@return the device handler

*/

rt_err_t dht_init(struct dht_device dev, const rt_base_t pin)

{

if(dev == NULL)

return -RT_ERROR;

dev->type = DHT_TYPE;

dev->pin = pin;

rt_memset(dev->data, 0, DHT_DATA_SIZE);

rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);

return RT_EOK;

}

// 1、初始化类型

dht_device_t dht_create(const rt_base_t pin)

{

dht_device_t dev;

dev = rt_calloc(1, sizeof(struct dht_device));

if (dev == RT_NULL)

{

LOG_E(“Can’t allocate memory for dhtxx device”);

return RT_NULL;

}

dev->type = DHT_TYPE;

dev->pin = pin;

rt_memset(dev->data, 0, DHT_DATA_SIZE);

rt_pin_mode(dev->pin, PIN_MODE_INPUT_PULLUP);

return dev;

}

void dht_delete(dht_device_t dev)

{

if (dev)

rt_free(dev);

}

/

Copyright (c) 2006-2021, RT-Thread Development TeamSPDX-License-Identifier: Apache-2.0

Change Logs:

Date Author Notes

2023-03-01 DYC the first version

/

#ifndef SRC_DHT11_H_

#define SRC_DHT11_H_

#include

#include

#include

#include

#include

#define DHTLIB_VERSION “0.9.0”

#define DHT_DATA_SIZE 5

/ sensor model type */

#define DHT11 0

#define DHT_TYPE DHT11

struct dht_device

{

rt_base_t pin;

rt_uint8_t type;

rt_uint8_t data[DHT_DATA_SIZE];

rt_mutex_t lock;

};

typedef struct dht_device *dht_device_t;

dht_device_t dht_create(const rt_base_t pin);

void dht_delete(dht_device_t dev);

rt_err_t dht_init(struct dht_device *dev, const rt_base_t pin);

rt_bool_t dht_read(dht_device_t dev);

rt_int32_t dht_get_humidity(dht_device_t dev);

rt_int32_t dht_get_temperature(dht_device_t dev);

float convert_c2k(float c);//将摄氏温度转为开氏温度

float convert_c2f(float c);//将摄氏温度转为华氏温度

float convert_f2c(float f);//将华氏温度转为摄氏温度

rt_int32_t split_int(const rt_int32_t num, rt_int32_t *integer,

rt_int32_t *decimal, const rt_uint32_t times);

rt_err_t rt_hw_dht_init(const char *name, struct rt_sensor_config cfg);

#endif / SRC_DHT11_H_ */

这里DHT11 使用的是 GPIO 0208,所以需要把这个引脚配置为输入模式

五、烧录验证