查看: 653|回复: 1

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

[复制链接]

116

主题

133

帖子

3768

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
3768
发表于 2023-2-8 09:32:45 | 显示全部楼层 |阅读模式
【瑞萨RA4系列开发板体验】板载按键的切换按键和普通按键用法
作者:HonestQiao


在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,除非松开后,再次按下。
根据这个逻辑,我们使用如下的代码来实现:

  1. void hal_entry(void)
  2. {
  3.     fsp_err_t err;                                       //
  4.     err = R_IOPORT_Open(&g_ioport_ctrl, &g_bsp_pin_cfg); // 初始化引脚
  5.     assert(FSP_SUCCESS == err);                          // 判断是否初始化成功

  6.     bsp_io_level_t Pin_P005; // 定义获取函数的结构体
  7.     bsp_io_level_t Pin_P006; // 定义获取函数的结构体
  8.     int status[] = {0, 0};
  9.     int count[] = {0};
  10.     while (1)
  11.     {
  12.         R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_05, &Pin_P005); // 运行函数并把获取的数据赋值结构体
  13.         if (Pin_P005 == BSP_IO_LEVEL_LOW && status[0] == 0)
  14.         { // 判断按键有没有按下
  15.             status[0] = 1;
  16.             count[0]++;
  17.         }
  18.         else if (Pin_P005 == BSP_IO_LEVEL_HIGH && status[0] == 1)
  19.         { // 判断按键有没有松开
  20.             status[0] = 0;
  21.         }
  22.         if (count[0] % 2 == 0)
  23.         {
  24.             R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW); // 关闭LED
  25.         }
  26.         else
  27.         {
  28.             R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH); // 点亮LED
  29.         }

  30.         R_IOPORT_PinRead(&g_ioport_ctrl, BSP_IO_PORT_00_PIN_06, &Pin_P006); // 运行函数并把获取的数据赋值结构体
  31.         if (Pin_P006 == BSP_IO_LEVEL_LOW)
  32.         { // 判断按键有没有按下
  33.             status[1] = 1;
  34.         }
  35.         else if (Pin_P006 == BSP_IO_LEVEL_HIGH)
  36.         { // 判断按键有没有松开
  37.             status[1] = 0;
  38.         }
  39.         if (status[1] == 1)
  40.         {
  41.             R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_HIGH); // 点亮LED
  42.         }
  43.         else
  44.         {
  45.             R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_04, BSP_IO_LEVEL_LOW); // 关闭LED
  46.         }
  47.     }

  48. #if BSP_TZ_SECURE_BUILD
  49.     /* Enter non-secure code */
  50.     R_BSP_NonSecureEnter();
  51. #endif
  52. }
复制代码
再上述代码中,设置了一个status,用来记录两个按键的状态;一个count,用来给按键1计数。
从上述代码可以看到,对于LED1,取计数值对2的余数,为0则熄灭,为1则点亮,也就是奇数点亮,偶数熄灭。
对于LED2,则根据按键2的状态,你按下我就亮,你松开我就熄灭。
要使用上述的代码,需要先在RASC中,做好对应引脚的配置,确保LED1、LED2对应的引脚为输出,而SW1、SW2对应的引脚为输入。


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



回复

使用道具 举报

3

主题

195

帖子

1191

积分

金牌会员

Rank: 6Rank: 6

积分
1191
发表于 2023-3-14 10:57:28 | 显示全部楼层

不错,学习一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

用户排行榜

RA助手

主题: 116帖子:133精华:0

RA_Lance

主题: 92帖子:132精华:9

lugl

主题: 38帖子:126精华:0

xujiwei263

主题: 16帖子:73精华:0

books咦

主题: 11帖子:11精华:2

Juggernaut

主题: 9帖子:95精华:0
快速回复 返回顶部 返回列表