[i=s] 本帖最后由 go2world 于 2026-6-12 09:52 编辑 [/i]
【瑞萨 RA-Eco-RA2L1 开发板评测】GPIO 输入输出驱动开发指南
本文档详细介绍 RA-Eco-RA2L1 开发板的 GPIO 输入输出驱动开发,包含 LED 输出控制、按键输入检测(轮询方式),基于官方 FSP 库和野火开发实战指南。
一、硬件介绍
1.1 RA-Eco-RA2L1 开发板 GPIO 资源
| 外设 |
引脚 |
说明 |
有效电平 |
| LED1 |
P103 |
用户 LED1 |
高电平点亮 |
| LED2 |
P104 |
用户 LED2 |
高电平点亮 |
| KEY1(SW2) |
P001 |
用户按键1 |
低电平按下 |
| KEY2(SW3) |
P002 |
用户按键2 |
低电平按下 |
| 复位按键 |
RES |
系统复位 |
低电平复位 |
1.2 GPIO 工作模式
RA2L1 的 GPIO 支持以下模式:
| 模式 |
说明 |
| Input Mode |
输入模式,可配置上拉电阻 |
| Output Mode (Initial High) |
输出模式,初始高电平 |
| Output Mode (Initial Low) |
输出模式,初始低电平 |
| Output Mode (Initial Peripherals) |
输出模式,初始外设控制 |
1.3 FSP 中 IOPORT 属性说明
| 属性 |
描述 |
| Mode |
IO 引脚工作模式,支持输入/输出模式 |
| Pull up |
配置 IO 引脚是否使能上拉 |
| Drive Capacity |
配置 IO 引脚的驱动能力 |
| Output type |
配置输出类型,可选 CMOS 推挽输出或开漏输出 |
二、GPIO 输出开发(LED 控制)
2.1 新建工程
- 打开 e² studio
- 点击 文件 → 新建 → 瑞萨 C/C++ 项目 → Renesas RA
- 选择 Renesas RA C/C++ Project,点击 下一步
- 配置工程:
- Project Name:
RA2L1_GPIO_LED
- Location:纯英文路径
- FSP Version:6.4.0(或已安装版本)
- Device:
R7FA2L1AB2DFL
- Board:RA-Eco-RA2L1-48PIN-V2.0
- Toolchain:GNU ARM Embedded
- Debugger:J-Link(或实际使用的调试器)
- 点击 完成
2.2 FSP 配置步骤
步骤 1:配置 LED 引脚
-
打开 FSP Configuration 窗口
-
切换到 Pins 标签页
-
依次展开:Pin Function → Ports → P1

-
找到 P103 和 P104,配置如下:
| 引脚 |
Mode |
说明 |
| P103 |
Output Mode (Initial Low) |
LED1,初始低电平(熄灭) |
| P104 |
Output Mode (Initial Low) |
LED2,初始低电平(熄灭) |


- 按 Ctrl + S 保存配置
- 点击右上角 Generate Project Content 生成配置代码
步骤 2:验证配置
打开工程目录下 ra_gen/pin_data.c 源文件,可看到 g_bsp_pin_cfg_data 数组中已加入 LED 引脚的配置数据。

2.3 代码实现
2.3.1 基础版 hal_entry 实现(不封装驱动)
#include "hal_data.h"
void hal_entry(void)
{
/* TODO: add your own code here */
/* 初始化配置引脚(R_BSP_WarmStart 中已初始化,此处重复调用也不会报错) */
R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
while(1)
{
// 两个 LED 亮(高电平点亮)
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_HIGH);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_HIGH);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // 延时 500ms
// 两个 LED 灭
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, BSP_IO_LEVEL_LOW);
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_04, BSP_IO_LEVEL_LOW);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // 延时 500ms
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
2.3.2 用到的 FSP 库函数说明
1. R_IOPORT_Open - 初始化 IOPORT 模块
fsp_err_t R_IOPORT_Open(ioport_ctrl_t * const p_ctrl, ioport_cfg_t const * const p_cfg);
| 参数 |
说明 |
p_ctrl |
传入控制块 &g_ioport_ctrl |
p_cfg |
传入配置参数 g_ioport.p_cfg |
2. R_IOPORT_PinWrite - 控制引脚输出电平
fsp_err_t R_IOPORT_PinWrite(ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t level);
| 参数 |
说明 |
p_ctrl |
控制句柄,传入 &g_ioport_ctrl |
pin |
引脚编号,如 BSP_IO_PORT_01_PIN_03 |
level |
输出电平:BSP_IO_LEVEL_LOW / BSP_IO_LEVEL_HIGH |
3. R_BSP_SoftwareDelay - 软件延时
void R_BSP_SoftwareDelay(uint32_t delay, bsp_delay_units_t units);
| 参数 |
说明 |
delay |
延时时间量 |
units |
时间单位 |
|
BSP_DELAY_UNITS_SECONDS:秒 |
|
BSP_DELAY_UNITS_MILLISECONDS:毫秒 |
|
BSP_DELAY_UNITS_MICROSECONDS:微秒 |
2.3.3 封装 LED 驱动版本(规范开发)
头文件 src/led/bsp_led.h:
#ifndef BSP_LED_H
#define BSP_LED_H
#include "hal_data.h"
/* LED 引脚定义 - RA-Eco-RA2L1 开发板 */
#define LED1_PIN BSP_IO_PORT_01_PIN_03
#define LED2_PIN BSP_IO_PORT_01_PIN_04
/* LED 引脚置高电平,LED 亮 */
#define LED1_ON R_IOPORT_PinWrite(&g_ioport_ctrl, LED1_PIN, BSP_IO_LEVEL_HIGH)
#define LED2_ON R_IOPORT_PinWrite(&g_ioport_ctrl, LED2_PIN, BSP_IO_LEVEL_HIGH)
/* LED 引脚置低电平,LED 灭 */
#define LED1_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, LED1_PIN, BSP_IO_LEVEL_LOW)
#define LED2_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, LED2_PIN, BSP_IO_LEVEL_LOW)
/* 寄存器方式实现 LED 翻转 */
#define LED1_TOGGLE R_PORT1->PODR ^= 1 << (LED1_PIN & 0xFF)
#define LED2_TOGGLE R_PORT1->PODR ^= 1 << (LED2_PIN & 0xFF)
/* LED 初始化函数声明 */
void LED_Init(void);
#endif /* BSP_LED_H */
源文件 src/led/bsp_led.c:
#include "bsp_led.h"
/* LED 初始化函数实现 */
void LED_Init(void)
{
/* FSP 配置已自动初始化,此函数可留空或重复初始化(不会报错) */
R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
}
优化后的 hal_entry.c:
#include "hal_data.h"
#include "led/bsp_led.h"
void hal_entry(void)
{
/* TODO: add your own code here */
LED_Init(); // LED 初始化
while(1)
{
LED1_ON; // LED1 亮
LED2_ON; // LED2 亮
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
LED1_OFF; // LED1 灭
LED2_OFF; // LED2 灭
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
2.4 下载验证
- 编译工程无错误后,将程序下载到开发板
- 按下开发板复位按键
- 观察两个用户 LED(P103、P104)同时闪烁,周期 1 秒(亮 500ms,灭 500ms)
- 验证功能正常
三、GPIO 输入开发(按键检测 - 轮询方式)
3.1 硬件设计
RA-Eco-RA2L1 开发板的按键为 低电平有效 设计:
- 按键未按下时:GPIO 引脚通过上拉电阻接电源,输入为高电平
- 按键按下时:GPIO 引脚接地,输入为低电平
3.2 新建工程
- 拷贝之前的
RA2L1_GPIO_LED 工程
- 重命名为
RA2L1_GPIO_Key
- 导入 e² studio 工作空间
- 在工程
src 目录下新建 key 文件夹
- 添加
bsp_key.c 和 bsp_key.h 两个文件
最终工程结构:
RA2L1_GPIO_Key/
├── src/
│ ├── led/
│ │ ├── bsp_led.c
│ │ └── bsp_led.h
│ ├── key/
│ │ ├── bsp_key.c
│ │ └── bsp_key.h
│ └── hal_entry.c
└── ...
3.3 FSP 配置步骤
配置按键引脚
- 打开工程的 FSP 配置界面
- 切换到 Pins 标签页
- 依次展开:Peripherals → I/O → P0
- 找到 P001 和 P002,配置如下:
| 引脚 |
Mode |
Pull up |
说明 |
| P001 |
Input Mode |
Enable |
按键 1(SW2) |
| P002 |
Input Mode |
Enable |
按键 2(SW3) |
- 保存配置(Ctrl + S)
- 点击 Generate Project Content 生成配置代码
注意:本章使用轮询方式检测按键,不启用外部中断(IRQ)。中断方式后续章节讲解。
3.4 代码实现
3.4.1 依赖的 FSP 库函数
读取引脚电平 - R_IOPORT_PinRead:
fsp_err_t R_IOPORT_PinRead(
ioport_ctrl_t * const p_ctrl, // IOPORT 控制句柄,默认传入 &g_ioport_ctrl
bsp_io_port_pin_t pin, // 要读取的引脚,类型为 bsp_io_port_pin_t 枚举
bsp_io_level_t * p_pin_value // 输出参数,接收读取到的引脚电平
);
bsp_io_level_t 枚举定义:
typedef enum e_bsp_io_level
{
BSP_IO_LEVEL_LOW = 0, // 低电平
BSP_IO_LEVEL_HIGH // 高电平
} bsp_io_level_t;
3.4.2 按键扫描函数(轮询方式)
源文件 src/key/bsp_key.c:
#include "bsp_key.h"
/* 按键状态宏定义 */
#define KEY_ON 1 // 按键按下
#define KEY_OFF 0 // 按键未按下
/**
* @brief 阻塞式按键扫描函数
* @param key 要扫描的按键引脚,如 KEY1_SW2_PIN
* @retval KEY_ON:按键按下;KEY_OFF:按键未按下
*/
uint32_t Key_Scan(bsp_io_port_pin_t key)
{
bsp_io_level_t state;
// 读取按键引脚当前电平
R_IOPORT_PinRead(&g_ioport_ctrl, key, &state);
if (BSP_IO_LEVEL_HIGH == state)
{
return KEY_OFF; // 高电平,按键未按下
}
else
{
// 低电平,按键已按下,等待按键释放
do {
R_IOPORT_PinRead(&g_ioport_ctrl, key, &state);
} while (BSP_IO_LEVEL_LOW == state); // 循环直到按键松开
}
return KEY_ON; // 按键按下并释放,返回按下标志
}
头文件 src/key/bsp_key.h:
#ifndef BSP_KEY_H
#define BSP_KEY_H
#include "hal_data.h"
/* RA-Eco-RA2L1 开发板按键引脚定义 */
#define KEY1_SW2_PIN BSP_IO_PORT_00_PIN_01
#define KEY2_SW3_PIN BSP_IO_PORT_00_PIN_02
uint32_t Key_Scan(bsp_io_port_pin_t key);
#endif /* BSP_KEY_H */
3.4.3 主逻辑入口函数
hal_entry.c:
#include "hal_data.h"
#include "led/bsp_led.h"
#include "key/bsp_key.h"
void hal_entry(void)
{
/* TODO: add your own code here */
/* 初始化外设 */
LED_Init();
while(1)
{
// 扫描按键 1,按下则翻转 LED1 状态
if (Key_Scan(KEY1_SW2_PIN) == KEY_ON)
{
LED1_TOGGLE;
}
// 扫描按键 2,按下则翻转 LED2 状态
if (Key_Scan(KEY2_SW3_PIN) == KEY_ON)
{
LED2_TOGGLE;
}
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
3.5 下载验证
- 将程序编译无误后,下载到开发板
- 按下开发板复位按键
- 按下用户按键 1(SW2):观察 LED1 灯状态翻转(亮→灭/灭→亮)
- 按下用户按键 2(SW3):观察 LED2 灯状态翻转
- 验证功能正常
四、GPIO 外部中断开发(按键检测 - 中断方式)
4.1 硬件设计
使用外部中断(ICU - Interrupt Control Unit)实现按键检测,支持低功耗唤醒。
4.2 FSP 配置步骤
步骤 1:配置按键引脚为外部中断模式
- 打开 FSP Configuration 窗口
- 切换到 Pins 标签页
- 依次展开:Peripherals → I/O → P0
- 找到 P001,配置如下:
| 属性 |
值 |
说明 |
| Mode |
Input Mode |
输入模式 |
| Pull up |
Enable |
使能上拉 |
| IRQ |
IRQ0 |
绑定到外部中断 0 |
- 找到 P002,配置如下:
| 属性 |
值 |
说明 |
| Mode |
Input Mode |
输入模式 |
| Pull up |
Enable |
使能上拉 |
| IRQ |
IRQ1 |
绑定到外部中断 1 |
步骤 2:配置外部中断栈
- 切换到 Stacks 标签页
- 点击 New Stack → Input → External IRQ (r_icu)
- 添加两个外部中断栈,分别配置:
IRQ0(按键 1)配置:
| 属性 |
值 |
| Name |
g_external_irq0 |
| Channel |
0 |
| Trigger |
Falling Edge(下降沿触发) |
| Callback |
key1_callback |
| Pin |
P001 |
IRQ1(按键 2)配置:
| 属性 |
值 |
| Name |
g_external_irq1 |
| Channel |
1 |
| Trigger |
Falling Edge(下降沿触发) |
| Callback |
key2_callback |
| Pin |
P002 |
- 保存配置并生成代码
4.3 代码实现
hal_entry.c:
#include "hal_data.h"
#include "led/bsp_led.h"
/* 外部中断回调函数 - 按键 1 */
void key1_callback(external_irq_callback_args_t *p_args)
{
(void)p_args;
LED1_TOGGLE; // 翻转 LED1 状态
}
/* 外部中断回调函数 - 按键 2 */
void key2_callback(external_irq_callback_args_t *p_args)
{
(void)p_args;
LED2_TOGGLE; // 翻转 LED2 状态
}
void hal_entry(void)
{
/* TODO: add your own code here */
/* 初始化外设 */
LED_Init();
/* 打开外部中断 */
R_ICU_ExternalIrqOpen(&g_external_irq0_ctrl, &g_external_irq0_cfg);
R_ICU_ExternalIrqOpen(&g_external_irq1_ctrl, &g_external_irq1_cfg);
/* 使能外部中断 */
R_ICU_ExternalIrqEnable(&g_external_irq0_ctrl);
R_ICU_ExternalIrqEnable(&g_external_irq1_ctrl);
while(1)
{
/* 主循环可以进入低功耗模式,等待中断唤醒 */
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
4.4 下载验证
- 编译并下载程序到开发板
- 按下复位按键
- 按下用户按键 1(SW2):LED1 状态翻转(中断触发)
- 按下用户按键 2(SW3):LED2 状态翻转(中断触发)
- 验证中断方式按键检测功能正常
五、总结
5.1 开发流程总结
新建工程 → FSP 引脚配置 → 生成代码 → 编写驱动代码 → 编译 → 烧录 → 验证
5.2 GPIO 开发要点
| 要点 |
说明 |
| FSP 配置 |
在 Pins 标签页配置引脚模式和属性 |
| 代码生成 |
配置完成后必须点击 Generate Project Content |
| 电平控制 |
使用 R_IOPORT_PinWrite() 控制输出 |
| 电平读取 |
使用 R_IOPORT_PinRead() 读取输入 |
| 中断配置 |
在 Pins 标签页绑定 IRQ,在 Stacks 标签页添加外部中断栈 |
5.3 常见问题
| 问题 |
原因 |
解决方案 |
| LED 不亮 |
引脚配置错误 |
检查 FSP 配置中的引脚号和模式 |
| 按键检测不灵敏 |
未使能上拉 |
在 FSP 配置中使能 Pull up |
| 中断不触发 |
未使能中断 |
调用 R_ICU_ExternalIrqEnable() |
六、参考资源
| 资源 |
链接 |
| 野火 RA FSP 库开发实战指南 |
https://doc.embedfire.com/mcu/renesas/fsp_ra/zh/latest/ |
| 瑞萨 FSP GitHub 仓库 |
https://github.com/renesas/fsp |
| RA-Eco-RA2L1 官方仓库 |
https://gitee.com/ramcu/ra-eco-ra2-l1-48-pin-v1.0 |
文档版本:v1.0
更新日期:2026-06-10
适用开发板:RA-Eco-RA2L1-48PIN-V2.0
适用 FSP 版本:6.4.0+