瑞萨单片机william hill官网
直播中

HonestQiao

8年用户 519经验值
擅长:嵌入式技术
私信 关注
[经验]

【瑞萨RA4系列开发板体验】板载按键的切换按键和普通按键用法

在RA4M2开发板上,有三个普通按键,两个电容按键。两个普通按键中,有一个是RESET按键,我们无法使用,另外的两个SW1、SW2则可以正常使用。
image.png

从原理图上,也可以更清晰的看到各自的用途:
image.png

之前做过基础流水灯的演示,那是GPIO输出,普通按键就是GPIO输入了。
两个按键,我们实现两种逻辑,分别为:

  • 按键1:按一次,切换一次LED1,也就是Toggle
  • 按键2:按住算通,松开算断,按下的时候,点亮LED2,松开的时候,熄灭LED2

在FSP用户手册中,专门提供了库函数,来操作GPIO端口:
image.png
我们要做普通按键检测和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); // 关闭LED
        }
        else
        {
            R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH); // 点亮LED
        }

        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); // 点亮LED
        }
        else
        {
            R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW); // 关闭LED
        }
    }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

再上述代码中,设置了一个status,用来记录两个按键的状态;一个count,用来给按键1计数。
从上述代码可以看到,对于LED1,取计数值对2的余数,为0则熄灭,为1则点亮,也就是奇数点亮,偶数熄灭。
对于LED2,则根据按键2的状态,你按下我就亮,你松开我就熄灭。

要使用上述的代码,需要先在RASC中,做好对应引脚的配置,确保LED1、LED2对应的引脚为输出,而SW1、SW2对应的引脚为输入。
image.png

编译上述代码并烧录到开发板以后,测试按键1和按键2,具体表现如下:

按键测试.gif

按键测试

更多回帖

发帖
×
20
完善资料,
赚取积分