Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
瑞萨-RTT活动
RT-Thread一般讨论
CPK-RA2L1评估板DHT11(3)
发布于 2023-03-12 20:05:48 浏览:347
订阅该版
[tocm] # 一、准备 本篇文章主要介绍使用RT-Thread Studio 和瑞萨 CPK-RA2L1评估板,使用大佬的轮子采集温湿度 # 二、硬件准备 CPK-RA2L1评估板, 这个板子的芯片型号是 R7FA2L1AB2DFM,DHT11 温湿度传感器。 ![1.png](https://oss-club.rt-thread.org/uploads/20230312/ac6443cd567ba12171f67742f7c6c18a.png.webp) # 三、新建工程 参考:[https://club.rt-thread.org/ask/article/7ef4e81b9075c00f.html] 需要注意这个DHT11的通信时序,此处把datasheet上传了 [DHT11 温湿度传感器变送器 探头.pdf](https://club.rt-thread.org/file_download/5fe15e929e206118) 1、总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。 ![2.png](https://oss-club.rt-thread.org/uploads/20230312/26d638017b6e241e7cab4b6a386c3cd1.png.webp) 2、总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态 ![3.png](https://oss-club.rt-thread.org/uploads/20230312/f1f4b28f9968a9e6ee21afeea962c7d0.png.webp) 3、数字0信号 ![4.png](https://oss-club.rt-thread.org/uploads/20230312/1c12a0f66343493af0c3927fbcd1f989.png.webp) 4、数字1信号 ![5.png](https://oss-club.rt-thread.org/uploads/20230312/0fc0350a6acf2b1c6caf0bf728606eca.png.webp) 四、驱动代码 ```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-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
data[i] = dht_read_byte(dev->pin); } #ifdef PKG_USING_DHTXX_INTERRUPT_DISABLE rt_hw_interrupt_enable(level); #endif /* Checksum */ for(i=0; i
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); } ``` ```c /* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-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,所以需要把这个引脚配置为输入模式 ![6.png](https://oss-club.rt-thread.org/uploads/20230312/06abdaa2987974b86809ea628866c3e4.png) 五、烧录验证 ![7.png](https://oss-club.rt-thread.org/uploads/20230312/695a63b61a73741d487a328aacfa40b6.png)
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
快乐小鸟
这家伙很懒,什么也没写!
文章
5
回答
0
被采纳
0
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
xusiwei1236
5
个答案
2
次被采纳
踩姑娘的小蘑菇
1
个答案
2
次被采纳
用户名由3_15位
7
个答案
1
次被采纳
bernard
4
个答案
1
次被采纳
张世争
1
个答案
1
次被采纳
本月文章贡献
聚散无由
2
篇文章
15
次点赞
catcatbing
2
篇文章
5
次点赞
Wade
2
篇文章
2
次点赞
Ghost_Girls
1
篇文章
6
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部