4.1 原理图分析
查看EK-RA6M4的原理图,如下图所示,该开发板上有2个用户按键。
![基于单片机的按键中断控制-单片机实现按键控制 基于单片机的按键中断控制-单片机实现按键控制](https://file.elecfans.com/web2/M00/82/00/pYYBAGORsYqAM9TzAABpZFM7JP0086.jpg)
根据原理图可知,这2个按键的控制逻辑为:
按键
S1
S2
引脚
P005
P006
电平
按键按下低电平、按键释放高电平
按键按下低电平、按键释放高电平
4.2 中断配置
首先,在FSP配置中将按键所用的两个GPIO口配置成中断模式。
![基于单片机的按键中断控制-单片机实现按键控制1 基于单片机的按键中断控制-单片机实现按键控制1](https://file.elecfans.com/web2/M00/82/00/pYYBAGORsYuACYTBAAP_IA9cjck431.jpg)
在这里,我们可以查找到 P005 、P006的中断号分别为 IRQ10 和 IRQ11;
接着选择 Stacks , 点击 “New Stack” -> “Input” -> “External IRQ(r_icu)” 添加外部中断协议栈。
![基于单片机的按键中断控制-单片机实现按键控制2 基于单片机的按键中断控制-单片机实现按键控制2](https://file.elecfans.com/web2/M00/81/77/poYBAGORsYqAS20aAAL8I0TQhyg505.jpg)
接下来配置相关的按键中断,并重新生成代码。
![基于单片机的按键中断控制-单片机实现按键控制3 基于单片机的按键中断控制-单片机实现按键控制3](https://file.elecfans.com/web2/M00/82/00/pYYBAGORsYuAG9VFAAOCSvb2cmI908.jpg)
通过 Name 字段可以修改按键中断的名称为 g_key1_irq,它将在IDE自动生成的文件 ra_gen/common_data.c/h 中定义按键操作相关的变量;
通过 Channel 字段可以修改按键的中断号,这里设置为10,下面的 Pins 将自动选择 P005 这个引脚;
通过 Trigger 字段可以修改中断的触发方式为下降沿触发;
通过 Callback 字段设置按键的中断回调函数,它将配置在 g_key1_irq_cfg 变量中,该函数需要我们自己实现;
另外,我们也可以在这里修改按键中断的优先级;
4.3 源码修改
创建按键操作相关的头文件 src/bsp_key.h 如下:
复制
#ifndef BSP_KEY_H_
#define BSP_KEY_H_
#define USER_KEY1_IRQ_NUMBER 10
#define USER_KEY2_IRQ_NUMBER 11
extern int key_init(void);
extern void icu_deinit(void);
#endif /* BSP_KEY_H_ */
创建按键操作相关的c文件 src/bsp_key.c 如下:
复制#
include
h>
#include “bsp_led.h”
#include “bsp_key.h”
#include “bsp_api.h”
#include “common_data.h”
int key_init(void)
{
int err = FSP_SUCCESS;
/* Open and enable key1 interrupt */
err = R_ICU_ExternalIrqOpen(&g_key1_irq_ctrl, &g_key1_irq_cfg);
if (FSP_SUCCESS != err)
{
printf (”
**R_ICU_ExternalIrqOpen API FAILED**
“);
return err;
}
err = R_ICU_ExternalIrqEnable(&g_key1_irq_ctrl);
if (FSP_SUCCESS != err)
{
printf (”
**R_ICU_ExternalIrqOpen API FAILED**
“);
return err;
}
/* Open and enable key1 interrupt */
err = R_ICU_ExternalIrqOpen(&g_key2_irq_ctrl, &g_key2_irq_cfg);
if (FSP_SUCCESS != err)
{
printf (”
**R_ICU_ExternalIrqOpen API FAILED**
“);
return err;
}
err = R_ICU_ExternalIrqEnable(&g_key2_irq_ctrl);
if (FSP_SUCCESS != err)
{
printf (”
**R_ICU_ExternalIrqOpen API FAILED**
“);
return err;
}
return err;
}
void icu_deinit(void)
{
R_ICU_ExternalIrqClose(&g_key1_irq_ctrl);
R_ICU_ExternalIrqClose(&g_key2_irq_ctrl);
}
void key_callback(external_irq_callback_args_t *p_args)
{
static bsp_led_status_t status[2] = { BSP_LEDON, BSP_LEDON};
if(USER_KEY1_IRQ_NUMBER == p_args->channel)
{
turn_led(BSP_LEDRED, status[0]);
status[0] ^= 1;
}
else if(USER_KEY2_IRQ_NUMBER == p_args->channel)
{
turn_led(BSP_LEDGREEN, status[1]); status[1] ^= 1;
}
}
按键回调函数 key_callback() 将分别通过两个按键控制 红绿两个灯的亮灭。
修改 src/hal_entry.c 源文件,在里面添加按键初始化代码并修改蓝色Led灯为系统运行的心跳灯状态。
复制… …
#include “bsp_key
.h”
… …
void hal_entry(void)
{
… …
key_init();
while (
1)
{
turn_led(BSP_LEDBLUE, BSP_LEDON);
delay_ms(
200);
turn_led(BSP_LEDBLUE, BSP_LEDOFF);
delay_ms(
200);
turn_led(BSP_LEDBLUE, BSP_LEDON);
delay_ms(
200);
turn_led(BSP_LEDBLUE, BSP_LEDOFF);
delay_ms(
200);
turn_led(BSP_LEDBLUE, BSP_LEDON);
delay_ms(
500);
turn_led(BSP_LEDBLUE, BSP_LEDOFF);
delay_ms(
1000);
}
}
4.4 编译运行
代码修改完成后,在开发板上编译运行,蓝色Led将作为系统状态心跳灯,而按下S1、S2将点亮红色和绿色Led,再次按下则将灭掉Led。
![基于单片机的按键中断控制-单片机实现按键控制4 基于单片机的按键中断控制-单片机实现按键控制4](https://file.elecfans.com/web2/M00/81/77/poYBAGORsYuAE4HFAAOAgP-HYdQ284.jpg)