05 GPIO输入-key实验

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

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

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


最后 key.c 和 key.h 加入到工程中。
FSP 配置
按键连接的引脚 IO 是 P600,按键检测的是按下松开的开关状态,所以需要读取 IO 的高低电平状态,IO 需要配置为输入模式。
Keil 界面选择“Tools”→“RA Smart Configurator”打开 RASC 界面。
在 FSP 配置界面里面点开 “Pins”→“Ports”→“P6”→“P600”,“Mode” 属性配置为 “Input Mode”,其他的属性默认即可。

①选择“Pins”,包含所有 IO 和外围设备。
②选择“Ports”。
③按键的 IO 引脚是 P600,选择 P6。
④选择 P6 端口的 00 引脚。
⑤设置 P600 IO 属性,Mode 模式选择“Input mode”,设置为输入。
| 配置项 | 取值/描述 |
|---|---|
| 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)
},
{
.pin = BSP_IO_PORT_06_PIN_00,
.pin_cfg = ((uint32_t) IOPORT_CFG_PORT_DIRECTION_INPUT)
},
};
在生成的 LED GPIO 配置后面增加一个 ioport_pin_cfg_t 数组项,P600 按键引脚,设置为输入模式。
在 r_ioport.h 中有如下定义了 IOPORT_CFG_PORT_DIRECTION_INPUT:
程序设计
程序的入口函数 main 函数调用了 hal_entry 函数。打开 \src\hal_entry.c 文件,在 hal_entry 函数里面编写代码。
实现按键控制 LED 灯的翻转效果,首先初始化配置 key 引脚,然后在一个死循环里面重复读取 key 引脚的电平,检测到低电平表示按键按下,等检测到高电平表示按键松开,整个过程代表一次按键操作。按一次翻转一次 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_PinRead (ioport_ctrl_t * const p_ctrl, bsp_io_port_pin_t pin, bsp_io_level_t * p_pin_value);
使用 R_IOPORT_PinRead 函数可以读取引脚的输入高低电平。第一个参数需要传入控制块 g_ioport_ctrl,第二个参数传入 IO 端口和引脚号,第三个参数返回 IO 引脚电平。
程序编写
在 bsp_io.h 中定义了 bsp_io_level_t 电平状态值。
/** Levels that can be set and read for individual pins */
typedef enum e_bsp_io_level
{
BSP_IO_LEVEL_LOW = 0, //< Low
BSP_IO_LEVEL_HIGH //< High
} bsp_io_level_t;
在 key.h 头文件里定义按键引脚、按键状态宏,如果有多个按键用于区分。定义按键初始化和按键扫描函数。
#ifndef __BSP_KEY_H
#define __BSP_KEY_H
#include "hal_data.h"
// 按键引脚定义
#define KEY1_PIN BSP_IO_PORT_06_PIN_00
/* 定义宏 KEY_ON 表示按键按下
定义宏 KEY_OFF 表示按键没有按下
*/
#define KEY_ON 1
#define KEY_OFF 0
// Key初始化函数
void key_Init(void);
uint32_t key_Scan(bsp_io_port_pin_t key);
#endif
在 key.c 里实现初始化函数和按键扫描函数。
#include "key.h"
// 按键初始化函数
void key_Init(void)
{
// 初始化配置引脚
R_IOPORT_Open (&g_ioport_ctrl, g_ioport.p_cfg);
}
/* 按键扫描函数(阻塞式)
* key: KEY1_PIN 用户按键1的引脚
*/
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; //按键被按下了
}
在 hal_entry.c 文件中添加对头文件 key.h 的包含,在 hal_entry 入口函数初始化 key,在循环中扫描按键,检测到按下就翻转 LED 灯状态。
void hal_entry(void)
{
/* TODO: add your own code here */
led_Init(); // LED 初始化
key_Init();
while(1)
{
if( key_Scan(KEY1_PIN) == KEY_ON ) //扫描按键1
{
LED1_TOGGLE(); //翻转LED1状态
}
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
下载验证
连接下载器,将程序编译并下载到开发板之后,按下复位按键来复位开发板,可以观察到按下松开按键 LED 灯亮,再次按键 LED 灯灭,重复操作,LED 灯状态翻转切换。