KEYSCAN使用指南*
第一章 概述*
按键扫描模块支持矩阵式和行列式 2 种扫描模式。用户可根据实际需求对按键的行列数量、消抖时间、中断类型进行配置。在不同的扫描模式下,单按键和组合按键有一定的使用条件,详见按键功能设计。
功能特性*
- 支持最大的矩阵式按键为
12 X 20
,支持最大的行列式按键为31 X 31
,模式可配置 按键扫描时钟
可配置(10kzh - 128khz)
按键扫描时间间隔
可配置按键消抖时间
可配置按键结束超时时间
可配置按键FIFO阈值
可配置按键中断类型使能
可配置按键行列的使用数量
可配置
功能设计*
矩阵式*
12 X 20 矩阵式原理图*
使用要求*
- 行列对应关系:
ROW1 ~ ROW12
对应P0 ~ P11
,COL1 ~ COL20
对应P12 ~ P31
; - 所有按键可以作为单按键使用;
- 组合按键不能形成直角三角形,否则会出现幻影键;
行列式*
31 X 31 行列式原理图*
使用要求*
- 行列对应关系:
ROW0 ~ ROW31
对应P0 ~ P31
,COL1~ 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