跳转至

KEYSCAN使用指南*

第一章 概述*

按键扫描模块支持矩阵式和行列式 2 种扫描模式。用户可根据实际需求对按键的行列数量、消抖时间、中断类型进行配置。在不同的扫描模式下,单按键和组合按键有一定的使用条件,详见按键功能设计。

功能特性*

  • 支持最大的矩阵式按键为 12 X 20,支持最大的行列式按键为 31 X 31,模式可配置
  • 按键扫描时钟可配置 (10kzh - 128khz)
  • 按键扫描时间间隔可配置
  • 按键消抖时间可配置
  • 按键结束超时时间可配置
  • 按键FIFO阈值可配置
  • 按键中断类型使能可配置
  • 按键行列的使用数量可配置

功能设计*

矩阵式*

12 X 20 矩阵式原理图*

img

使用要求*
  • 行列对应关系:ROW1 ~ ROW12 对应 P0 ~ P11COL1 ~ COL20 对应 P12 ~ P31
  • 所有按键可以作为单按键使用;
  • 组合按键不能形成直角三角形,否则会出现幻影键;

行列式*

31 X 31 行列式原理图*

img

使用要求*
  • 行列对应关系:ROW0 ~ ROW31 对应 P0 ~ P31COL1~ COL31 对应 P0 ~ P30
  • COL1 列的每个按键都可以作为单按键使用,其他按键不能够作为单按键使用,必须与 COL1 的任何一个按键一起组合使用,才能够被识别响应;

第二章 KEYSCAN示例参考*

按键配置*

  • 以下配置是矩阵式按键扫描的配置方式,例如apus/platform/boards/gx8301a_rc_demo/board_config.h

按键扫描配置*

  • 启用按键扫描:
#define BOARD_HAS_KEYSCAN 1

这行代码启用按键扫描功能。设置为 1 表示按键扫描是激活的。

  • 按键扫描模式:
#define KEYSCAN_MODE 0   /* 0: matrix; 1: determinant */

这行代码将按键扫描模式设置为矩阵扫描(0)。另一种模式是行列式扫描(1)。

矩阵配置*

  • 矩阵尺寸:
#define KEYSCAN_MATRIX_ROW_NUM    4
#define KEYSCAN_MATRIX_COL_NUM    3
#define KEYSCAN_MATRIX_KEY_NUM    10

这些行定义了一个4x3的矩阵,总共有10个按键。

  • 行和列引脚:
#define KEYSCAN_MATRIX_ROW1_PIN    P0_0
#define KEYSCAN_MATRIX_ROW2_PIN    P0_1
#define KEYSCAN_MATRIX_ROW3_PIN    P0_2
#define KEYSCAN_MATRIX_ROW4_PIN    P0_3
#define KEYSCAN_MATRIX_COL1_PIN    P3_1
#define KEYSCAN_MATRIX_COL2_PIN    P2_0
#define KEYSCAN_MATRIX_COL3_PIN    P2_1
  • 行和列引脚数组:
#define KEYSCAN_MATRIX_ROW_PINS    {KEYSCAN_MATRIX_ROW1_PIN, KEYSCAN_MATRIX_ROW2_PIN, KEYSCAN_MATRIX_ROW3_PIN, KEYSCAN_MATRIX_ROW4_PIN}
#define KEYSCAN_MATRIX_COL_PINS    {KEYSCAN_MATRIX_COL1_PIN, KEYSCAN_MATRIX_COL2_PIN, KEYSCAN_MATRIX_COL3_PIN}

这些数组将行和列引脚分组,以便在代码中更容易管理。

按键代码*

  • 按键代码定义:
#define K1_CODE (0)
#define K2_CODE (1)
#define K3_CODE (2)
#define K4_CODE (3)
#define K5_CODE (4)
#define K6_CODE (5)
#define K7_CODE (6)
#define K8_CODE (7)
#define K9_CODE (8)
#define KRT_CODE (9)

这些行定义了矩阵中每个按键的唯一代码,可以用来识别哪个按键被按下。

组合键定义*

#define APP_COMBO_KEY_BLE_PAIR (1 << (K41_CODE) | 1 << (K23_CODE))

行列式按键扫描的配置方式见apus/platform/boards/gx8301a_dev/board_config.h

按键初始化配置*

按键事件*

typedef enum {
    KEY_ACTION_NONE = 0,
    KEY_ACTION_RELEASE ,
    KEY_ACTION_PRESS,
    KEY_ACTION_SINGLE_CLICK,
    KEY_ACTION_DOUBLE_CLICK,
    KEY_ACTION_TRIPLE_CLICK,
    KEY_ACTION_REPEAT_CLICK,
    KEY_ACTION_LONGPRESS,
    KEY_ACTION_HOLD,
}keypress_action_e;
  • KEY_ACTION_NONE:值为 0,表示没有任何按键动作。
  • KEY_ACTION_RELEASE:表示按键被释放。
  • KEY_ACTION_PRESS:表示按键被按下。
  • KEY_ACTION_SINGLE_CLICK:表示按键被单击一次。
  • KEY_ACTION_DOUBLE_CLICK:表示按键被双击。
  • KEY_ACTION_TRIPLE_CLICK:表示按键被三击。
  • KEY_ACTION_REPEAT_CLICK:表示按键被重复点击。
  • KEY_ACTION_LONGPRESS:表示按键被长按。
  • KEY_ACTION_HOLD:表示按键被持续按住。

以上是KEYSCAN支持的按键事件,详细见apus/subsys/keypress/keypress_action.h

按键初始化*

/* 按键事件回调函数 */
static void _keypress_action_cb(unsigned char key_id, keypress_action_e action)
{
    key_args_t key;

    key.code = key_id;
    key.action = action;
    chip_os_queue_put(&_app_key_queue, &key);
    ble_npl_eventq_put(nimble_port_get_dflt_eventq(), &_app_key_event);
}

int app_key_init(app_key_handler_t key_handler)
{
#if BOARD_HAS_KEYSCAN
    keyscan_cfg_t keyscan_cfg = {0};
    keypress_action_cfg_t key_action_cfg = {0};

    chip_os_queue_init(&_app_key_queue, "_app_key_queue", &queue_pool[0], sizeof(key_args_t), sizeof(queue_pool));
    ble_npl_event_init(&_app_key_event, _app_key_event_proc, key_handler);

    keyscan_cfg.scan_itvl = 60;                             /* scan_itvl:扫描间隔,单位为毫秒 */
    keyscan_cfg.debounce_time = 40;                         /* debounce_time:去抖动时间,单位为毫秒。*/
    keyscan_cfg.scan_timeout = 240;                         /* scan_timeout:扫描超时时间,单位为毫秒。*/
    keyscan_cfg.scan_cb = _key_scan_handler;                /* scan_cb:扫描回调函数 */

    key_action_cfg.scan_itvl = keyscan_cfg.scan_itvl;
    key_action_cfg.click_delay = 150;                       /* click_delay:单击延迟时间,单位为毫秒 */
    key_action_cfg.longpress_time = 3000;                   /* longpress_time:长按时间,单位为毫秒 */
    key_action_cfg.hold_time = 5000;                        /* hold_time:按住时间,单位为毫秒 */
    keypress_action_init(&key_action_cfg, KEYSCAN_KEY_NUM, _app_key_action_pool, _keypress_action_cb);

    keyscan_init(&keyscan_cfg);
    keyscan_wakeup_enable();

    return 0;
#else
    return -1;
#endif
}

以上接口是按键初始化代码,详情见apus/apps/ble_remote_control/app_key/app_key.c