04 GPIO输出-led实验

开发板官网(https://www.edevkit.com/)
本系列教程目录:
- 瑞萨单片机开发教程[一] e2-studio + DAP LINK开发环境搭建
- 瑞萨单片机开发教程[二] Keil/RASC开发环境搭建
- 瑞萨单片机开发教程[三] 新建RASC工程
- 瑞萨单片机开发教程[四] GPIO输出——led实验
- 瑞萨单片机开发教程[五] GPIO输入——按键key实验
- 瑞萨单片机开发教程[六] ICU外部中断实验
- 瑞萨单片机开发教程[七] SCI UART串口通信实验
- 瑞萨单片机开发教程[八] DMAC 串口数据传输实验
- 瑞萨单片机开发教程[九] ADC 电压采集实验
GPIO 输出——点亮 LED 实验
本章目标:
- 熟悉 RASC 配置 IO 的操作使用
- 掌握 GPIO 读写 API 的使用
硬件设计
本实验使用开发板上的 LED 灯,通过 GPIO 输出控制其亮灭。
软件设计
新建工程
在 Keil 的工作空间中有一份之前的模板工程“03_template”,复制一份并将文件夹改名为“04 GPIO-led”。双击打开“EBF_RA6M5.uvprojx”工程,通过 Keil 的新建文件功能新建 led.c 和 led.h,保存到工程目录下的 src 文件夹中。

将代码文件放到 src 文件夹下之后,Keil 软件并不会自动将它们加入到工程中。这时需要打开 RASC 的 FSP 配置界面,点击一次界面中间的“Generate Project Content”按钮,自动生成文件架构,这样 src 文件夹下的代码文件就会被自动加入工程中。

接着关闭 FSP 配置界面返回到 Keil,进行一次编译后会弹出提示框,提示工程结构发生了变化,点击“是”即可。


最后 led.c 和 led.h 就加入到工程中了。
FSP 配置
在 Keil 界面选择“Tools”→“RA Smart Configurator”,打开 RASC 配置界面。
在 FSP 配置界面中依次点开“Pins”→“Ports”→“P4”→“P400”,然后将连接到 LED 灯的 IO 引脚的“Mode”属性配置为“Output mode (Initial High)”,表示该引脚默认输出高电平,其他属性保持默认即可。

① 选择“Pins”,包含所有 IO 和外围设备。
② 选择“Ports”。
③ LED 灯的 IO 引脚是 P400,选择 P4。
④ 选择 P4 端口的 00 引脚。
⑤ 设置 P400 的 IO 属性,Mode 模式选择“Output mode(Initial High)”,设置为输出。
| 配置项 | 取值/描述 |
|---|---|
| Mode | - “Input mode”(输入模式) - “Output mode(Initial Low)”(输出模式,初始电平为低) - “Output mode(Initial High)”(输出模式,初始电平为高) |
| Pull up(上拉电阻) | - “None”(禁止内部上拉) - “input pull-up”(使能内部上拉) 当引脚被配置为 Output mode 时无法设置 Pull up 参数 |
| IRQ(中断) | - “None”(不使用中断) - “IRQ10”(使用中断) |
| Output type(输出类型) | - “CMOS” - “n-ch open drain”(开漏) 当引脚被配置为 Input mode 时无法设置本参数 |
配置好引脚后,点击右上角的“Generate Project Content”就会生成代码。RASC 会为这些引脚生成配置信息,保存在 pin_data.c 文件中。
打开 pin_data.c 文件。
- 引脚配置信息
const ioport_pin_cfg_t g_bsp_pin_cfg_data[] = {
{
.pin = BSP_IO_PORT_01_PIN_08,
.pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG)
},
{
.pin = BSP_IO_PORT_03_PIN_00,
.pin_cfg = ((uint32_t) IOPORT_CFG_PERIPHERAL_PIN | (uint32_t) IOPORT_PERIPHERAL_DEBUG)
},
{
.pin = BSP_IO_PORT_04_PIN_00,
.pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_OUTPUT | (uint32_t) IOPORT_CFG_PORT_OUTPUT_HIGH)
},
};
对于要配置的每一个引脚,都会生成一个 ioport_pin_cfg_t 数组项。
typedef struct st_ioport_pin_cfg
{
uint32_t pin_cfg;//< 引脚的配置值,取值类型ioport_cfg_options_t
bsp_io_port_pin_t pin;// 引脚ID,即:哪个引脚
} ioport_pin_cfg_t;
指定引脚时需要 2 个参数:它是哪一组?它是这组里的哪一个?比如引脚 P400 属于第 4 组里的第 0 个引脚。在 bsp_io.h 中,为每一个引脚都定义了一个宏,比如:
typedef enum e_bsp_io_port_pin_t
{
BSP_IO_PORT_00_PIN_00 = 0x0000, ///< IO port 0 pin 0
BSP_IO_PORT_00_PIN_01 = 0x0001, ///< IO port 0 pin 1
...
BSP_IO_PORT_04_PIN_00 = 0x0400, ///< IO port 4 pin 0
...
}bsp_io_port_pin_t;
设置结构体里的 pin_cfg 成员,在 r_ioport_api.h 中有如下定义:
typedef enum e_ioport_cfg_options
{
IOPORT_CFG_PORT_DIRECTION_INPUT = 0x00000000, // 输入方向
IOPORT_CFG_PORT_DIRECTION_OUTPUT = 0x00000004, // 输出方向
IOPORT_CFG_PORT_OUTPUT_LOW = 0x00000000, // 低电平
IOPORT_CFG_PORT_OUTPUT_HIGH = 0x00000001, // 高电平
IOPORT_CFG_PULLUP_ENABLE = 0x00000010, // 使能内部上拉电阻
IOPORT_CFG_PIM_TTL = 0x00000020, // 使能引脚的输入模式
IOPORT_CFG_NMOS_ENABLE = 0x00000040, // NMOS output,NMOS开漏输出
IOPORT_CFG_PMOS_ENABLE = 0x00000080, // PMOS output, PMOS开漏输出
IOPORT_CFG_DRIVE_MID = 0x00000400, // 引脚驱动能力为中等
IOPORT_CFG_DRIVE_HS_HIGH = 0x00000800, // 引脚驱动能力为高,并且支持高速率
IOPORT_CFG_DRIVE_MID_IIC = 0x00000C00, // 引脚的输出能力可用于I2C的20mA端口
IOPORT_CFG_DRIVE_HIGH = 0x00000C00, ///< Sets pin drive output to high
IOPORT_CFG_EVENT_RISING_EDGE = 0x00001000, // 事件触发方式为上升沿
IOPORT_CFG_EVENT_FALLING_EDGE = 0x00002000, // 事件触发方式为下降沿
IOPORT_CFG_EVENT_BOTH_EDGES = 0x00003000, // 事件触发方式为双边沿
IOPORT_CFG_IRQ_ENABLE = 0x00004000, // 使能引脚的中断功能
IOPORT_CFG_ANALOG_ENABLE = 0x00008000, // 引脚用作模拟信号
IOPORT_CFG_PERIPHERAL_PIN = 0x00010000 // 引脚用作外设的引脚
} ioport_cfg_options_t;
程序设计
程序的入口函数 main 调用了 hal_entry 函数。打开 src/hal_entry.c 文件,在 hal_entry 函数中编写代码。
实现 LED 灯的闪烁效果,首先初始化配置 LED 引脚,然后在一个死循环里面重复以下流程:LED 灯亮,延时 1s,LED 灯灭,延时 1s,然后 LED 灯又亮。如此反复循环,就能实现 LED 灯的闪烁效果。
- 初始化 IOPORT 模块
//调用 R_IOPORT_Open 函数来初始化 IOPORT 模块
R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
通过 R_IOPORT_Open 函数来初始化 IOPORT 模块。调用 R_IOPORT_Open 函数时,需要传入控制块参数 g_ioport_ctrl 和配置参数 g_ioport.p_cfg。
- 控制 IO 输出高低电平
fsp_err_t R_IOPORT_PinWrite (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t level);
使用 R_IOPORT_PinWrite 函数可以控制引脚输出的高低电平,从而控制 LED 灯的亮灭。第一个参数需要传入控制块 g_ioport_ctrl,第二个参数传入 IO 端口和引脚号,第三个参数传入 IO 引脚电平。
- 延时函数
void R_BSP_SoftwareDelay (uint32_t delay, bsp_delay_units_t units);
使用 R_BSP_SoftwareDelay 函数可以进行延时,第一个参数表示延时的时间量,第二个参数表示时间单位。
时间单位参数可选:
BSP_DELAY_UNITS_SECONDS,表示秒;BSP_DELAY_UNITS_MILLISECONDS,表示毫秒;BSP_DELAY_UNITS_MICROSECONDS,表示微秒。
程序编写
在 led.h 头文件中定义 LED 控制宏并声明初始化函数。
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "hal_data.h"
// LED引脚置低电平 LED灯亮
#define LED1_ON R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_00, BSP_IO_LEVEL_LOW)
// LED引脚置高电平 LED灯灭
#define LED1_OFF R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_00, BSP_IO_LEVEL_HIGH)
// 使用寄存器来实现 LED灯翻转
#define LED1_TOGGLE R_PORT4->PODR ^= 1<<(BSP_IO_PORT_04_PIN_00 & 0xFF)
// LED初始化函数
void led_Init(void);
#endif
在 led.c 中实现初始化函数。
#include "led.h"
// LED初始化函数
void led_Init(void)
{
//初始化配置引脚
R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
}
在 hal_entry.c 文件中添加对 led.h 头文件的包含,在 hal_entry 入口函数中初始化 LED 并实现 LED 闪烁。
void hal_entry(void)
{
/* TODO: add your own code here */
led_Init(); // LED 初始化
while(1)
{
LED1_ON(); // LED1亮
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
LED1_OFF(); // LED1灭
R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS); //延时1秒
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
下载验证
连接下载器,将程序编译并下载到开发板之后,按下复位按键复位开发板,可以观察到开发板上的 LED1 灯以亮 1s、灭 1s 的方式循环闪烁。