跳到主要内容

05 GPIO输入-key实验

在这里插入图片描述

开发板官网https://www.edevkit.com/)

本系列教程目录:


GPIO 输入——按键 Key 实验

本章目标:

  • 熟悉 RASC 配置 IO 的操作使用
  • 掌握 GPIO 的读写 API 的使用

硬件设计

本实验使用开发板上的按键,通过 GPIO 输入检测按键状态,并控制 LED 灯的翻转。

软件设计

新建工程

按键检测需要用到 LED,复制一份“04 GPIO-led”修改文件夹名“05 GPIO-key”,双击打开“EBF_RA6M5.uvprojx”工程,通过 Keil 的新建文件功能新建 key.ckey.h,保存到工程目录下的 \src 文件夹下。

插图01

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

插图02

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

插图03

插图04

最后 key.ckey.h 加入到工程中。

FSP 配置

按键连接的引脚 IO 是 P600,按键检测的是按下松开的开关状态,所以需要读取 IO 的高低电平状态,IO 需要配置为输入模式。

Keil 界面选择“Tools”→“RA Smart Configurator”打开 RASC 界面。

在 FSP 配置界面里面点开 “Pins”→“Ports”→“P6”→“P600”,“Mode” 属性配置为 “Input Mode”,其他的属性默认即可。

插图05

①选择“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 文件。

  1. 引脚配置信息
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 的闪烁效果。

  1. 初始化 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

  1. 读取 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 灯状态翻转切换。