在RA4M2开发板上,有三个普通按键,两个电容按键。两个普通按键中,有一个是RESET按键,我们无法使用,另外的两个SW1、SW2则可以正常使用。
从原理图上,也可以更清晰的看到各自的用途:
之前做过基础流水灯的演示,那是GPIO输出,普通按键就是GPIO输入了。
两个按键,我们实现两种逻辑,分别为:
- 按键1:按一次,切换一次LED1,也就是Toggle
- 按键2:按住算通,松开算断,按下的时候,点亮LED2,松开的时候,熄灭LED2
在FSP用户手册中,专门提供了库函数,来操作GPIO端口:
我们要做普通按键检测和LED控制,目前只需要关注上图中红框的调用即可。
类似这样的库函数,FSP提供了成百上千个,随着学习的深入会了解的越来越多。
三个我们需要关注的调用:
R_IOPORT_Open
:初始化GPIO引脚配置
R_IOPORT_PinRead
:读取GPIO的状态
R_IOPORT_PinWrite
:输出到GPIO
要实现按键2的功能,很简单,直接使用 R_IOPORT_PinRead
读取按键的状态,然后根据读取的结果,设定对应的LED是亮还是灭。
按键1的功能,则需要一点点小的技巧。我们可以先设置一个计数器,默认为0,当检测到按键按下的时候,计数器+1,然后,当计数器值为奇数的时候,点亮对应的LED,当为偶数的时候,熄灭对应的LED,这样每按键一次,就实现了一次LED切换。
然而,这里存在一个问题,如果一直按着不动,那一直能检测到按键按下,计数器就会不停地+1,LED灯也会跟着不停地亮灭亮灭亮灭。
这显然不是我们所期望的。
于是,我们还需要再设置一个状态变量,默认为0,当按下后,设置其状态为1,表示按下了,同时计数器+1。当按下的同时,还需要检测状态如果为0,也就是表示之前为没有按下的状态,这时候才设置状态ww1,并计算器+1;如果松开了,则设置状态为0,计数器值不变。
经过这样的处理,一直按着不动的时候,状态变量变为1后,后续的检测将不会造成计数器持续的+1,除非松开后,再次按下。
根据这个逻辑,我们使用如下的代码来实现:
void hal_entry(void)
{
fsp_err_t err;
err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg);
assert(FSP_SUCCESS == err);
bsp_io_level_t Pin_P005;
bsp_io_level_t Pin_P006;
int status[] = {0, 0};
int count[] = {0};
while (1)
{
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &Pin_P005);
if (Pin_P005 == BSP_IO_LEVEL_LOW && status[0] == 0)
{
status[0] = 1;
count[0]++;
}
else if (Pin_P005 == BSP_IO_LEVEL_HIGH && status[0] == 1)
{
status[0] = 0;
}
if (count[0] % 2 == 0)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
}
else
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);
}
R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &Pin_P006);
if (Pin_P006 == BSP_IO_LEVEL_LOW)
{
status[1] = 1;
}
else if (Pin_P006 == BSP_IO_LEVEL_HIGH)
{
status[1] = 0;
}
if (status[1] == 1)
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH);
}
else
{
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW);
}
}
#if BSP_TZ_SECURE_BUILD
R_BSP_NonSecureEnter();
#endif
}
再上述代码中,设置了一个status,用来记录两个按键的状态;一个count,用来给按键1计数。
从上述代码可以看到,对于LED1,取计数值对2的余数,为0则熄灭,为1则点亮,也就是奇数点亮,偶数熄灭。
对于LED2,则根据按键2的状态,你按下我就亮,你松开我就熄灭。
要使用上述的代码,需要先在RASC中,做好对应引脚的配置,确保LED1、LED2对应的引脚为输出,而SW1、SW2对应的引脚为输入。
编译上述代码并烧录到开发板以后,测试按键1和按键2,具体表现如下: