eefocus_3947073 发表于 2026-6-22 09:38:31

【瑞萨EK-RA4C1】LED点灯测试

GPIO 与板载 LED 测试为 GPIO 输入输出实验提供了最直接的目标。下面从资源配置到代码实现,完整演练一遍。9.1 板载 LED 与按键资源回顾在第二章硬件解读中已经提到,EK-RA4C1 的生态系统与系统控制区集成了以下用户交互资源:
资源数量丝印对应 GPIO说明


红色 LED1LED1P400高电平点亮
蓝色 LED1LED2P401高电平点亮
绿色 LED1LED3P402高电平点亮
用户按键2S1 (USER)P004按下低电平,外部上拉
用户按键2S2 (USER)P005按下低电平,外部上拉
复位按键1RES—系统复位







三个 LED 的设计对调试非常友好——红色用于错误/告警指示,绿色用于正常运行状态,蓝色可用于特殊的模式标识(如蓝牙连接、OTA 升级等)。两颗用户按键则为交互式功能切换提供了可能(例如下面将要演示的"按键切换 LED 闪烁模式")。9.2 RASC 配置 GPIO在 FSP Configuration 的 "Pins" 标签页中,依次配置以下引脚:
引脚功能方向初始电平


P400红色 LEDOutput (Initial Low)低(熄灭)
P401蓝色 LEDOutput (Initial Low)低(熄灭)
P402绿色 LEDOutput (Initial Low)低(熄灭)
P004用户按键 S1Input—
P005用户按键 S2Input—







对于按键引脚,需额外在 Pin Configuration 中将 Pull-up 设为 Enabled,或将 IRQ 按需配置(本节采用轮询方式读取,不使能中断)。无需在 "Stacks" 标签页添加额外驱动栈——GPIO 属于 BSP 层面的基础功能,RASC 生成代码后直接调用 R_BSP_PinWrite() / R_BSP_PinRead() 即可。点击 "Generate Project Content" 生成代码。9.3 示例代码以下代码在上一章串口测试工程的基础上扩展,实现三个功能层次:
[*]基础闪烁:三色 LED 顺序交替点亮(红→蓝→绿→全灭,循环)
[*]RGB 混色:利用 PWM 思路通过 GPIO 软件模拟实现呼吸渐变效果(红蓝色交叉产生紫色过渡)
[*]按键交互:按下 S1 切换 LED 演示模式,按下 S2 暂停/恢复
完整 src/hal_entry.c 代码如下(保留上一章的 UART 初始化部分,新增 LED 驱动逻辑):c

#include "hal_data.h"#include <stdio.h>#include <string.h>/* --- 引脚宏定义,与 RASC 配置保持一致 --- */#define LED_RED_PIN   BSP_IO_PORT_04_PIN_00   /* P400: 红色 LED */#define LED_BLUE_PIN    BSP_IO_PORT_04_PIN_01   /* P401: 蓝色 LED */#define LED_GREEN_PIN   BSP_IO_PORT_04_PIN_02   /* P402: 绿色 LED */#define BTN_S1_PIN      BSP_IO_PORT_00_PIN_04   /* P004: 用户按键 S1 */#define BTN_S2_PIN      BSP_IO_PORT_00_PIN_05   /* P005: 用户按键 S2 *//* --- LED 演示模式枚举 --- */typedef enum {    LED_MODE_SEQUENTIAL = 0,    /* 模式0: 红→蓝→绿 顺序闪烁 */    LED_MODE_BREATHING,         /* 模式1: RGB 呼吸混色效果 */    LED_MODE_ALL_BLINK,         /* 模式2: 三色同闪 */    LED_MODE_MAX} led_mode_t;/* --- 全局变量 --- */static volatile led_mode_t g_led_mode = LED_MODE_SEQUENTIAL;static volatile bool       g_paused    = false;/* ======================== UART 部分(保留) ======================== */static volatile uint8_tg_rx_byte;static volatile bool   g_rx_complete = false;void uart0_callback(uart_callback_args_t *p_args){    switch (p_args->event)    {    case UART_EVENT_RX_CHAR:      g_rx_byte      = *(uint8_t *)(p_args->p_context);      g_rx_complete= true;      break;    case UART_EVENT_TX_COMPLETE:    case UART_EVENT_ERR_PARITY:    case UART_EVENT_ERR_FRAMING:    case UART_EVENT_ERR_OVERFLOW:    default:      break;    }}#ifdef __GNUC__int _write(int fd, char *buf, int len){    (void)fd;    R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)buf, (uint32_t)len);    while (0U == g_uart0_ctrl.tx_data_bytes) { }    return len;}#endif/* ======================== LED 控制函数 ======================== *//* 关闭所有 LED */static void led_all_off(void){    R_BSP_PinWrite(LED_RED_PIN,   BSP_IO_LEVEL_LOW);    R_BSP_PinWrite(LED_BLUE_PIN,BSP_IO_LEVEL_LOW);    R_BSP_PinWrite(LED_GREEN_PIN, BSP_IO_LEVEL_LOW);}/* 点亮指定 LED */static void led_on(uint16_t pin){    R_BSP_PinWrite(pin, BSP_IO_LEVEL_HIGH);}/* 熄灭指定 LED */static void led_off(uint16_t pin){    R_BSP_PinWrite(pin, BSP_IO_LEVEL_LOW);}/* 简单毫秒级延时(基于循环计数,非精确) */static void simple_delay_ms(uint32_t ms){    R_BSP_SoftwareDelay(ms, BSP_DELAY_UNITS_MILLISECONDS);}/* 按键扫描:检测下降沿(按下瞬间),带简易去抖 */static bool button_pressed(uint16_t pin){    /* 读当前状态(按下为低电平) */    if (BSP_IO_LEVEL_LOW == R_BSP_PinRead(pin))    {      simple_delay_ms(20);/* 去抖延时 */      if (BSP_IO_LEVEL_LOW == R_BSP_PinRead(pin))      {            /* 等待按键释放 */            while (BSP_IO_LEVEL_LOW == R_BSP_PinRead(pin)) { }            return true;      }    }    return false;}/* ======================== LED 演示模式 ======================== *//* 模式0:红→蓝→绿 顺序轮闪 */static void mode_sequential(void){    printf(" Mode 0: Sequential Blink\r\n");    led_all_off();    led_on(LED_RED_PIN);    simple_delay_ms(500);    led_all_off();    led_on(LED_BLUE_PIN);    simple_delay_ms(500);    led_all_off();    led_on(LED_GREEN_PIN);    simple_delay_ms(500);    led_all_off();    simple_delay_ms(300);}/* 模式1:RGB 呼吸混色 — 通过 GPIO 快速切换模拟视觉混合 */static void mode_breathing(void){    printf(" Mode 1: RGB Breathing Mix\r\n");    /* 红→紫(红+蓝)→蓝→青(蓝+绿)→绿 渐变循环 */    static const uint16_t seq[ = {      LED_RED_PIN,                              /* 纯红 */      (uint16_t)(LED_RED_PIN| 0x8000),      /* 红+蓝(标记位指示混色)*/      LED_BLUE_PIN,                           /* 纯蓝 */      (uint16_t)(LED_GREEN_PIN | 0x8000),       /* 蓝+绿 */      LED_GREEN_PIN                           /* 纯绿 */    };    for (int i = 0; i < 5; i++)    {      led_all_off();      if (seq[i & 0x8000)      {            /* 混色:快速交替点亮两个 LED,视觉上产生混合色 */            uint16_t pin_a = seq[i & 0x7FFF;            uint16_t pin_b = (i == 1) ? LED_BLUE_PIN : LED_GREEN_PIN;            for (int t = 0; t < 60; t++)            {                led_on(pin_a);                R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);                led_off(pin_a);                led_on(pin_b);                R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);                led_off(pin_b);            }      }      else      {            /* 单色:渐亮渐灭模拟呼吸 */            for (int t = 0; t < 80; t++)            {                led_on(seq[i);                R_BSP_SoftwareDelay(2 * (80 - t) / 80 + 1, BSP_DELAY_UNITS_MILLISECONDS);                led_off(seq[i);                R_BSP_SoftwareDelay(2 * t / 80 + 1, BSP_DELAY_UNITS_MILLISECONDS);            }      }    }}/* 模式2:三色同频闪烁 */static void mode_all_blink(void){    printf(" Mode 2: All Blink Together\r\n");    for (int i = 0; i < 4; i++)    {      led_on(LED_RED_PIN);      led_on(LED_BLUE_PIN);      led_on(LED_GREEN_PIN);      simple_delay_ms(200);      led_all_off();      simple_delay_ms(200);    }}/* 按键处理:模式切换与暂停控制 */static void handle_buttons(void){    if (button_pressed(BTN_S1_PIN))    {      g_led_mode = (led_mode_t)((g_led_mode + 1) % LED_MODE_MAX);      printf(" S1 pressed, switch to Mode %d\r\n", g_led_mode);    }    if (button_pressed(BTN_S2_PIN))    {      g_paused = !g_paused;      printf(" S2 pressed, LED %s\r\n", g_paused ? "PAUSED" : "RESUMED");    }}/* ======================== 主入口 ======================== */void hal_entry(void){    fsp_err_t err;    /* --- UART 初始化 --- */    err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);    if (FSP_SUCCESS != err)    {      /* 初始化失败:红灯快速闪烁报警 */      while (1)      {            led_on(LED_RED_PIN);            R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);            led_off(LED_RED_PIN);            R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);      }    }    /* --- GPIO 初始状态 --- */    led_all_off();    /* --- 打印启动信息 --- */    printf("\r\n========================================\r\n");    printf("EK-RA4C1 LED & Button Demo\r\n");    printf("LED:Red=P400Blue=P401Green=P402\r\n");    printf("BTN:S1=P004S2=P005\r\n");    printf("S1: Toggle Mode|S2: Pause/Resume\r\n");    printf("========================================\r\n");    /* --- 主循环 --- */    while (1)    {      /* 按键扫描 */      handle_buttons();      /* 暂停时仅扫描按键,不执行 LED 逻辑 */      if (g_paused)      {            R_BSP_SoftwareDelay(50, BSP_DELAY_UNITS_MILLISECONDS);            continue;      }      /* 根据当前模式执行 LED 演示 */      switch (g_led_mode)      {      case LED_MODE_SEQUENTIAL:            mode_sequential();            break;      case LED_MODE_BREATHING:            mode_breathing();            break;      case LED_MODE_ALL_BLINK:            mode_all_blink();            break;      default:            break;      }      /* 串口回环处理 */      if (g_rx_complete)      {            g_rx_complete = false;            R_SCI_UART_Write(&g_uart0_ctrl, &g_rx_byte, 1);            if ('\r' == g_rx_byte || '\n' == g_rx_byte)            {                uint8_t lf = '\n';                R_SCI_UART_Write(&g_uart0_ctrl, &lf, 1);            }      }    }}

代码结构说明:
模块关键函数功能


基础控制led_on() / led_off() / led_all_off()单灯开关、全灭
模式0mode_sequential()红→蓝→绿 顺序闪烁,每色保持 500ms
模式1mode_breathing()单色呼吸渐变 + 双色高速交替实现混色效果(R+G=**, R+B=紫)
模式2mode_all_blink()三色同频快闪,4 轮
按键管理button_pressed()带 20ms 去抖 + 抬起检测的按键扫描
主控handle_buttons()S1 循环切模式,S2 暂停/恢复







9.4 编译烧录与实物效果编译:与上一章流程一致,Build Project 后确认 0 errors, 0 warnings。烧录:通过板载 J-Link OB 下载,Debug 按钮一键完成。预期实物效果:
阶段板载现象串口输出


上电复位三灯瞬灭 → 进入模式0EK-RA4C1 LED & Button Demo 启动横幅
模式0 运行亮 500ms → 灭 500ms ,循环 Mode 0: Sequential Blink
按 S1 一次切换到模式1 S1 pressed, switch to Mode 1
模式1 运行快速闪烁 Mode 1: RGB Breathing Mix
按 S1 两次切换到模式2 S1 pressed, switch to Mode 2
模式2 运行同时快闪(200ms 亮 / 200ms 灭,共 4 轮后循环) Mode 2: All Blink Together
按 S2LED 保持当前状态定格暂停 S2 pressed, LED PAUSED
再按 S2LED 恢复动画 S2 pressed, LED RESUMED







9.5 测试小结
[*]FSP GPIO API 极简高效:R_BSP_PinWrite() / R_BSP_PinRead() 两个函数覆盖全部 GPIO 操作,无需初始化结构体、无需使能时钟——RASC 生成代码时已自动处理好引脚方向、上下拉和初始电平,业务代码只需关注逻辑。
[*]BSP 级别的引脚宏定义规范:BSP_IO_PORT_04_PIN_00 这种三层结构(端口/位)的宏命名清晰易读,配合 R_BSP_PinWrite() 使用,可读性远超裸寄存器操作 PORT4.PODR.BIT.B0 = 1。
[*]按键去抖的通用方案:button_pressed() 采用 20ms 延时二次确认 + 等待释放的组合策略,适用于大多数机械按键场景,可靠性良好。若需要更低的 CPU 占用,可改用定时器中断 + 状态机方式。
[*]软件模拟混色效果可行但有限:通过 GPIO 快速切换红蓝两色模拟紫色的效果在肉眼观察下可辨,但由于没有硬件 PWM 驱动,亮度和色彩精度受限。RA4C1 具备 32 位 GPT 定时器,若需要精确调光,下一步可尝试用 GPT 的 PWM 输出模式驱动 LED。

页: [1]
查看完整版本: 【瑞萨EK-RA4C1】LED点灯测试

Baidu
map