RA-Eco-RA6M4开发板实战:集成DHT11实现温湿度采集与多端显示
在完成RA-Eco-RA6M4开发板的串口通信与OLED显示功能调试后,本次实践将进一步集成DHT11温湿度传感器,通过单总线通信实现环境温湿度的数据采集,并将采集到的信息同步通过OLED屏幕可视化展示与串口打印输出,完整实现“传感器采集-数据处理-多端呈现”的闭环功能。
一、核心器件原理:DHT11单总线通信机制
DHT11是一款低成本、数字输出的温湿度复合传感器,其核心通信依赖单总线协议,仅需一根数据线即可完成主机与从机的数据交互,硬件连接简单但对通信时序要求严格。
1. 单总线基础特性
- 总线结构:仅需1根DATA线,传感器与开发板的GPIO口连接时,需外接4.7kΩ上拉电阻——闲置时总线被拉为高电平,确保信号稳定;设备通过漏极开路/三态端口接入,避免总线冲突。
- 通信逻辑:采用“主从模式”,仅当主机(RA6M4开发板)主动发起呼叫时,从机(DHT11)才会应答;若时序错误(如信号时长不匹配),传感器将直接无响应。
2. 数据传输规则
DHT11一次通信传输40位二进制数据,采用“高位先出”格式,具体组成如下:
8位湿度整数数据 + 8位湿度小数数据 + 8位温度整数数据 + 8位温度小数数据 + 8位校验位
- 校验规则:前4字节数据之和的低8位 = 校验位,用于验证数据有效性;
- 精度说明:湿度测量范围20%-90%RH(精度±5%RH),温度测量范围0℃-50℃(精度±2℃),小数位通常为0(简化应用场景下可忽略)。
二、硬件连接方案
本次硬件搭建以RA6M4开发板为核心,联动DHT11、OLED模块与串口,具体接线如下表所示,重点确保DHT11的DATA线时序稳定性。
| 器件 |
引脚/接口 |
RA6M4开发板引脚 |
辅助元件 |
|---|
| DHT11 |
VCC |
3.3V |
- |
| DHT11 |
GND |
GND |
- |
| DHT11 |
DATA |
P301(GPIO) |
4.7kΩ上拉电阻 |
| OLED(I2C) |
SCL |
P100 |
- |
| OLED(I2C) |
SDA |
P101 |
10K上拉电阻×2 |
| OLED |
VCC/GND |
3.3V/GND |
- |
| 串口模块 |
TX/RX |
对应UART9引脚 |
- |
注意:DHT11的DATA线切勿直接接5V引脚,RA6M4的GPIO口耐受3.3V电压,错接可能损坏芯片;上拉电阻需紧贴DATA线与3.3V之间,减少信号衰减。
三、软件配置:基于e2studio的开发环境搭建
本次开发使用e2studio IDE,结合瑞萨FSP(Flexible Software Package)配置工具,完成引脚定义、模块初始化等基础配置,核心步骤如下:
1. 项目结构规划
在原有“串口+OLED”项目基础上,新增DHT11相关驱动文件,形成模块化结构,便于维护:
DHT11_demo/
├─ src/
│ ├─ dht11/
│ │ ├─ bsp_dht11.c
│ │ └─ bsp_dht11.h
│ ├─ oled/
│ ├─ uart/
│ └─ hal_entry.c
└─ ra_cfg/
2. 关键引脚配置(Pin Configuration)
通过e2studio的“Pin Selection”工具配置P301引脚(DHT11的DATA线),参数如下:
- Port: P3,Pin: 01(即P301)
- Mode: Output mode(初始高电平)
- Pull-up/Pull-down: None(依赖外部4.7kΩ上拉)
- Drive Capacity: Low
- Output Type: CMOS
配置完成后,点击“Generate Project Content”生成引脚配置代码(g_bsp_pin_cfg)。
3. FSP模块初始化
无需额外启用FSP的专用模块,仅通过GPIO的电平翻转与延时函数模拟单总线时序,因此重点确保以下基础模块已初始化:
- IOPORT: 控制GPIO引脚电平(用于发送/接收单总线信号);
- UART9: 用于串口打印温湿度数据(复用原有初始化函数
UART9_Init());
- 延迟函数: 依赖
R_BSP_SoftwareDelay()实现微秒级/毫秒级延时(单总线时序核心)。
四、核心代码实现与解析
代码设计遵循“模块化”原则:bsp_dht11.c封装DHT11的底层时序操作,hal_entry.c实现整体逻辑调度(初始化-采集-显示)。
1. DHT11驱动封装(bsp_dht11.c/h)
核心功能是通过GPIO模拟单总线时序,实现“主机发起请求-从机应答-数据接收-校验”的完整流程,关键函数如下:
(1)引脚电平控制宏定义(bsp_dht11.h)
为简化代码,定义DATA线的电平读写宏,便于后续时序调整:
#include "hal_data.h"
#define DHT11_DATA_PORT BSP_IO_PORT_03
#define DHT11_DATA_PIN BSP_IO_PIN_01
#define DHT11_DATA_HIGH() R_IOPORT_PinWrite(&g_ioport_ctrl, DHT11_DATA_PIN, BSP_IO_LEVEL_HIGH)
#define DHT11_DATA_LOW() R_IOPORT_PinWrite(&g_ioport_ctrl, DHT11_DATA_PIN, BSP_IO_LEVEL_LOW)
#define DHT11_DATA_READ() R_IOPORT_PinRead(&g_ioport_ctrl, DHT11_DATA_PIN)
fsp_err_t DHT11_Init(void);
fsp_err_t DHT11_ReadData(uint8_t *hum_int, uint8_t *hum_dec, uint8_t *temp_int, uint8_t *temp_dec);
(2)初始化函数:DHT11_Init()
主机通过拉低DATA线至少18ms,发起启动信号,随后释放总线等待传感器应答:
fsp_err_t DHT11_Init(void)
{
DHT11_DATA_LOW();
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
DHT11_DATA_HIGH();
R_BSP_SoftwareDelay(30, BSP_DELAY_UNITS_MICROSECONDS);
if(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW)
{
while(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW);
while(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH);
return FSP_SUCCESS;
}
return FSP_ERR_INVALID_STATE;
}
(3)数据读取函数:DHT11_ReadData()
解析传感器返回的40位数据,按格式提取温湿度,并通过校验位验证有效性:
static uint8_t DHT11_ReadBit(void)
{
uint8_t bit = 0;
DHT11_DATA_LOW();
R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MICROSECONDS);
DHT11_DATA_HIGH();
while(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(27, BSP_DELAY_UNITS_MICROSECONDS);
if(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH) bit = 1;
while(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW);
return bit;
}
static uint8_t DHT11_ReadByte(void)
{
uint8_t byte = 0;
for(uint8_t i=0; i<8; i++)
{
byte <<= 1;
byte |= DHT11_ReadBit();
}
return byte;
}
fsp_err_t DHT11_ReadData(uint8_t *hum_int, uint8_t *hum_dec, uint8_t *temp_int, uint8_t *temp_dec)
{
uint8_t buf[5] = {0};
if(DHT11_Init() != FSP_SUCCESS)
return FSP_ERR_IO;
for(uint8_t i=0; i<5; i++)
{
buf[i] = DHT11_ReadByte();
}
if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4])
{
*hum_int = buf[0];
*hum_dec = buf[1];
*temp_int = buf[2];
*temp_dec = buf[3];
return FSP_SUCCESS;
}
return FSP_ERR_DATA_CORRUPT;
}
2. 主函数逻辑:hal_entry.c
主函数负责统筹各模块初始化,通过循环实现“LED闪烁提示-温湿度采集-OLED显示-串口打印”的周期性执行:
#include "hal_data.h"
#include "bsp_dht11.h"
#include "bsp_oled.h"
#include "bsp_uart9.h"
uint8_t hum_int = 0, hum_dec = 0;
uint8_t temp_int = 0, temp_dec = 0;
void hal_entry(void)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_03_PIN_01, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
UART9_Init();
LED_Init();
OLED_Init();
OLED_Clear();
OLED_ShowChinese(0, 0, 9);
OLED_ShowChinese(16, 0, 10);
OLED_ShowString(32, 0, "RA6M4", 16);
OLED_ShowString(0, 2, "TEMP: ", 16);
OLED_ShowString(0, 4, "HUMD: ", 16);
printf("RA6M4 + DHT11 温湿度采集系统启动!\r\n");
R_BSP_SoftwareDelay(2, BSP_DELAY_UNITS_SECONDS);
while(1)
{
LED1_ON;
LED2_ON;
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
LED1_OFF;
LED2_OFF;
if(DHT11_ReadData(&hum_int, &hum_dec, &temp_int, &temp_dec) == FSP_SUCCESS)
{
printf("湿度:%d.%d %%RH | 温度:%d.%d ℃\r\n", hum_int, hum_dec, temp_int, temp_dec);
OLED_ShowNum(64, 2, temp_int, 2, 16);
OLED_ShowString(80, 2, "℃", 16);
OLED_ShowNum(64, 4, hum_int, 2, 16);
OLED_ShowString(80, 4, "%", 16);
}
else
{
printf("数据采集失败,请检查DHT11连接或时序!\r\n");
}
R_BSP_SoftwareDelay(2, BSP_DELAY_UNITS_SECONDS);
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
五、功能测试与结果验证
1. 测试环境
- 供电:开发板通过USB接电脑(5V转3.3V);
- 工具:串口调试助手(波特率115200,8位数据位,1位停止位,无校验);
- 环境:室温25℃,室内湿度50%RH左右。
2. 测试结果
(1)串口输出
串口调试助手持续打印有效数据,无校验失败提示,示例如下:
RA6M4 + DHT11 温湿度采集系统启动!
湿度:51.0
湿度:51.0
湿度:52.0
(2)OLED显示
屏幕清晰显示“瑞萨RA6M4”标题,以及实时更新的“TEMP: 25℃”和“HUMD: 51%”,无乱码或闪烁现象。
(3)状态提示
LED1与LED2每1秒同步闪烁一次,表明系统正常运行;若DHT11连接松动,串口会打印“数据采集失败”提示,便于故障排查。
六、实操注意事项与问题排查
- 时序敏感问题:单总线对延时精度要求高,若使用
R_BSP_SoftwareDelay()延时不准(如优化等级过高),可改用定时器中断实现微秒级延时;
- 上拉电阻不可缺:未接4.7kΩ上拉电阻时,DATA线信号易受干扰,导致传感器无应答;
- 引脚复用冲突:P301若被其他模块(如定时器)占用,需在FSP配置中解除复用,确保为纯GPIO功能;
- 电源稳定性:# RA-Eco-RA6M4开发板实战:集成DHT11实现温湿度采集与多端显示
在完成RA-Eco-RA6M4开发板的串口通信与OLED显示功能调试后,本次实践将进一步集成DHT11温湿度传感器,通过单总线通信实现环境温湿度的数据采集,并将采集到的信息同步通过OLED屏幕可视化展示与串口打印输出,完整实现“传感器采集-数据处理-多端呈现”的闭环功能。
一、核心器件原理:DHT11单总线通信机制
DHT11是一款低成本、数字输出的温湿度复合传感器,其核心通信依赖单总线协议,仅需一根数据线即可完成主机与从机的数据交互,硬件连接简单但对通信时序要求严格。
1. 单总线基础特性
- 总线结构:仅需1根DATA线,传感器与开发板的GPIO口连接时,需外接4.7kΩ上拉电阻——闲置时总线被拉为高电平,确保信号稳定;设备通过漏极开路/三态端口接入,避免总线冲突。
- 通信逻辑:采用“主从模式”,仅当主机(RA6M4开发板)主动发起呼叫时,从机(DHT11)才会应答;若时序错误(如信号时长不匹配),传感器将直接无响应。
2. 数据传输规则
DHT11一次通信传输40位二进制数据,采用“高位先出”格式,具体组成如下:
8位湿度整数数据 + 8位湿度小数数据 + 8位温度整数数据 + 8位温度小数数据 + 8位校验位
- 校验规则:前4字节数据之和的低8位 = 校验位,用于验证数据有效性;
- 精度说明:湿度测量范围20%-90%RH(精度±5%RH),温度测量范围0℃-50℃(精度±2℃),小数位通常为0(简化应用场景下可忽略)。
二、硬件连接方案
本次硬件搭建以RA6M4开发板为核心,联动DHT11、OLED模块与串口,具体接线如下表所示,重点确保DHT11的DATA线时序稳定性。
| 器件 |
引脚/接口 |
RA6M4开发板引脚 |
辅助元件 |
|---|
| DHT11 |
VCC |
3.3V |
- |
| DHT11 |
GND |
GND |
- |
| DHT11 |
DATA |
P301(GPIO) |
4.7kΩ上拉电阻 |
| OLED(I2C) |
SCL |
P100 |
- |
| OLED(I2C) |
SDA |
P101 |
10K上拉电阻×2 |
| OLED |
VCC/GND |
3.3V/GND |
- |
| 串口模块 |
TX/RX |
对应UART9引脚 |
- |
注意:DHT11的DATA线切勿直接接5V引脚,RA6M4的GPIO口耐受3.3V电压,错接可能损坏芯片;上拉电阻需紧贴DATA线与3.3V之间,减少信号衰减。
三、软件配置:基于e2studio的开发环境搭建
本次开发使用e2studio IDE,结合瑞萨FSP(Flexible Software Package)配置工具,完成引脚定义、模块初始化等基础配置,核心步骤如下:
1. 项目结构规划
在原有“串口+OLED”项目基础上,新增DHT11相关驱动文件,形成模块化结构,便于维护:
DHT11_demo/
├─ src/
│ ├─ dht11/
│ │ ├─ bsp_dht11.c
│ │ └─ bsp_dht11.h
│ ├─ oled/
│ ├─ uart/
│ └─ hal_entry.c
└─ ra_cfg/
2. 关键引脚配置(Pin Configuration)
通过e2studio的“Pin Selection”工具配置P301引脚(DHT11的DATA线),参数如下:
- Port: P3,Pin: 01(即P301)
- Mode: Output mode(初始高电平)
- Pull-up/Pull-down: None(依赖外部4.7kΩ上拉)
- Drive Capacity: Low
- Output Type: CMOS
配置完成后,点击“Generate Project Content”生成引脚配置代码(g_bsp_pin_cfg)。
3. FSP模块初始化
无需额外启用FSP的专用模块,仅通过GPIO的电平翻转与延时函数模拟单总线时序,因此重点确保以下基础模块已初始化:
- IOPORT: 控制GPIO引脚电平(用于发送/接收单总线信号);
- UART9: 用于串口打印温湿度数据(复用原有初始化函数
UART9_Init());
- 延迟函数: 依赖
R_BSP_SoftwareDelay()实现微秒级/毫秒级延时(单总线时序核心)。
四、核心代码实现与解析
代码设计遵循“模块化”原则:bsp_dht11.c封装DHT11的底层时序操作,hal_entry.c实现整体逻辑调度(初始化-采集-显示)。
1. DHT11驱动封装(bsp_dht11.c/h)
核心功能是通过GPIO模拟单总线时序,实现“主机发起请求-从机应答-数据接收-校验”的完整流程,关键函数如下:
(1)引脚电平控制宏定义(bsp_dht11.h)
为简化代码,定义DATA线的电平读写宏,便于后续时序调整:
#include "hal_data.h"
#define DHT11_DATA_PORT BSP_IO_PORT_03
#define DHT11_DATA_PIN BSP_IO_PIN_01
#define DHT11_DATA_HIGH() R_IOPORT_PinWrite(&g_ioport_ctrl, DHT11_DATA_PIN, BSP_IO_LEVEL_HIGH)
#define DHT11_DATA_LOW() R_IOPORT_PinWrite(&g_ioport_ctrl, DHT11_DATA_PIN, BSP_IO_LEVEL_LOW)
#define DHT11_DATA_READ() R_IOPORT_PinRead(&g_ioport_ctrl, DHT11_DATA_PIN)
fsp_err_t DHT11_Init(void);
fsp_err_t DHT11_ReadData(uint8_t *hum_int, uint8_t *hum_dec, uint8_t *temp_int, uint8_t *temp_dec);
(2)初始化函数:DHT11_Init()
主机通过拉低DATA线至少18ms,发起启动信号,随后释放总线等待传感器应答:
fsp_err_t DHT11_Init(void)
{
DHT11_DATA_LOW();
R_BSP_SoftwareDelay(20, BSP_DELAY_UNITS_MILLISECONDS);
DHT11_DATA_HIGH();
R_BSP_SoftwareDelay(30, BSP_DELAY_UNITS_MICROSECONDS);
if(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW)
{
while(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW);
while(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH);
return FSP_SUCCESS;
}
return FSP_ERR_INVALID_STATE;
}
(3)数据读取函数:DHT11_ReadData()
解析传感器返回的40位数据,按格式提取温湿度,并通过校验位验证有效性:
static uint8_t DHT11_ReadBit(void)
{
uint8_t bit = 0;
DHT11_DATA_LOW();
R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MICROSECONDS);
DHT11_DATA_HIGH();
while(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(27, BSP_DELAY_UNITS_MICROSECONDS);
if(DHT11_DATA_READ() == BSP_IO_LEVEL_HIGH) bit = 1;
while(DHT11_DATA_READ() == BSP_IO_LEVEL_LOW);
return bit;
}
static uint8_t DHT11_ReadByte(void)
{
uint8_t byte = 0;
for(uint8_t i=0; i<8; i++)
{
byte <<= 1;
byte |= DHT11_ReadBit();
}
return byte;
}
fsp_err_t DHT11_ReadData(uint8_t *hum_int, uint8_t *hum_dec, uint8_t *temp_int, uint8_t *temp_dec)
{
uint8_t buf[5] = {0};
if(DHT11_Init() != FSP_SUCCESS)
return FSP_ERR_IO;
for(uint8_t i=0; i<5; i++)
{
buf[i] = DHT11_ReadByte();
}
if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4])
{
*hum_int = buf[0];
*hum_dec = buf[1];
*temp_int = buf[2];
*temp_dec = buf[3];
return FSP_SUCCESS;
}
return FSP_ERR_DATA_CORRUPT;
}
2. 主函数逻辑:hal_entry.c
主函数负责统筹各模块初始化,通过循环实现“LED闪烁提示-温湿度采集-OLED显示-串口打印”的周期性执行:
#include "hal_data.h"
#include "bsp_dht11.h"
#include "bsp_oled.h"
#include "bsp_uart9.h"
uint8_t hum_int = 0, hum_dec = 0;
uint8_t temp_int = 0, temp_dec = 0;
void hal_entry(void)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_03_PIN_01, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
UART9_Init();
LED_Init();
OLED_Init();
OLED_Clear();
OLED_ShowChinese(0, 0, 9);
OLED_ShowChinese(16, 0, 10);
OLED_ShowString(32, 0, "RA6M4", 16);
OLED_ShowString(0, 2, "TEMP: ", 16);
OLED_ShowString(0, 4, "HUMD: ", 16);
printf("RA6M4 + DHT11 温湿度采集系统启动!\r\n");
R_BSP_SoftwareDelay(2, BSP_DELAY_UNITS_SECONDS);
while(1)
{
LED1_ON;
LED2_ON;
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
LED1_OFF;
LED2_OFF;
if(DHT11_ReadData(&hum_int, &hum_dec, &temp_int, &temp_dec) == FSP_SUCCESS)
{
printf("湿度:%d.%d %%RH | 温度:%d.%d ℃\r\n", hum_int, hum_dec, temp_int, temp_dec);
OLED_ShowNum(64, 2, temp_int, 2, 16);
OLED_ShowString(80, 2, "℃", 16);
OLED_ShowNum(64, 4, hum_int, 2, 16);
OLED_ShowString(80, 4, "%", 16);
}
else
{
printf("数据采集失败,请检查DHT11连接或时序!\r\n");
}
R_BSP_SoftwareDelay(2, BSP_DELAY_UNITS_SECONDS);
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
五、功能测试与结果验证
1. 测试环境
- 供电:开发板通过USB接电脑(5V转3.3V);
- 工具:串口调试助手(波特率115200,8位数据位,1位停止位,无校验);
- 环境:室温25℃,室内湿度50%RH左右。
2. 测试结果
(1)串口输出
串口调试助手持续打印有效数据,无校验失败提示,示例如下:
RA6M4 + DHT11 温湿度采集系统启动!
湿度:51.0
湿度:51.0
湿度:52.0
(2)OLED显示
屏幕清晰显示“瑞萨RA6M4”标题,以及实时更新的“TEMP: 25℃”和“HUMD: 51%”,无乱码或闪烁现象。
(3)状态提示
LED1与LED2每1秒同步闪烁一次,表明系统正常运行;若DHT11连接松动,串口会打印“数据采集失败”提示,便于故障排查。
六、实操注意事项与问题排查
- 时序敏感问题:单总线对延时精度要求高,若使用
R_BSP_SoftwareDelay()延时不准(如优化等级过高),可改用定时器中断实现微秒级延时;
- 上拉电阻不可缺:未接4.7kΩ上拉电阻时,DATA线信号易受干扰,导致传感器无应答;
- 引脚复用冲突:P301若被其他模块(如定时器)占用,需在FSP配置中解除复用,确保为纯GPIO功能;
- 电源稳定性:DHT11供电波动可能导致数据跳变,可在VCC与GND间并联100nF电容滤波。
七、总结
本次实践基于RA-Eco-RA6M4开发板,成功集成DHT11温湿度传感器,核心收获包括:
- 掌握单总线协议的时序设计要点,理解“电平翻转+精准延时”是数字传感器通信的核心;
- 强化模块化编程思维,通过驱动封装实现代码复用与维护便捷性;
- 验证了RA6M4 GPIO口的灵活性,以及e2studio+FSP工具链在嵌入式开发中的高效性。
后续可进一步拓展功能,如通过蓝牙模块将温湿度数据上传至手机,或添加阈值报警(当温度超过30℃时LED常亮提示)。DHT11供电波动可能导致数据跳变,可在VCC与GND间并联100nF电容滤波。
七、总结
本次实践基于RA-Eco-RA6M4开发板,成功集成DHT11温湿度传感器,核心收获包括:
- 掌握单总线协议的时序设计要点,理解“电平翻转+精准延时”是数字传感器通信的核心;
- 强化模块化编程思维,通过驱动封装实现代码复用与维护便捷性;
- 验证了RA6M4 GPIO口的灵活性,以及e2studio+FSP工具链在嵌入式开发中的高效性。
后续可进一步拓展功能,如通过蓝牙模块将温湿度数据上传至手机,或添加阈值报警(当温度超过30℃时LED常亮提示)。