目录
目录
前言
DTS配置的参考
内核配置的参考
验证测试的参考
常见问题
驱动匹配失败
按键无响应
按键误触发或重复触发
无法唤醒系统
键值上报错误
总结
前言
矩阵键盘(Matrix Keypad)是一种通过行列扫描实现多按键识别的电路设计,可显著减少I/O占用。
其核心原理与实现方法如下:
1. 结构设计
将按键排列为行(Row)和列(Column)的矩阵形式,每个按键位于行线与列线的交叉点。例如4x4矩阵仅需8个I/O(4行+4列)即可检测16个按键。
2. 电平检测机制
按键闭合时,对应行线与列线导通,通过扫描行列电平变化确定按键位置。
3. 扫描方法
逐行扫描法:
步骤1:所有列线置低电平,检测行线是否有低电平(判断是否有按键按下)。
步骤2:逐列置低电平,检测行线变化,定位具体按键。
线反转法:
通过交替反转行/列电平状态,结合逻辑运算快速定位按键,适用于高速扫描场景。
矩阵按键是嵌入式系统中常用的输入设备,其中Linux内核自带的驱动核心源码位于`linux-x.xx/drivers/input/keyboard/matrix_keypad.c`,原生的参考文档路径位于`linux-x.xx/Documentation/devicetree/bindings/input/gpio-matrix-keypad.txt`和`linux-x.xx/Documentation/devicetree/bindings/input/matrix-keymap.txt`。
DTS配置的参考
matrix-keypad { compatible = "gpio-matrix-keypad"; /* 匹配驱动名称 */ debounce-delay-ms = <60>; /* 按键消抖延时(推荐10~20ms,需要根据具体硬件调整) */ col-scan-delay-us = <60>; /* 列扫描间隔(推荐10~50us,避免信号串扰) */ linux,no-autorepeat = <1>; /* 禁止按键自动重复 */ linux,wakeup = <0>; /* 支持系统唤醒 */ wakeup-source = <0>; gpio-activelow = <1>; /* GPIO低电平有效 */ drive-inactive-cols = <0>; /* 在扫描过程中驱动非活动列,默认情况下是将非活动列转换为输入 */ keypad,num-rows = <4>; /* 行GPIO引脚数量 */ keypad,num-columns = <4>; /* 列GPIO引脚数量 */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_row_gpios>; row-gpios = < /* 行GPIO引脚(包含引脚编号与电平属性) */ &gpioe 5 GPIO_ACTIVE_HIGH &gpioc 22 GPIO_ACTIVE_HIGH &gpioc 26 GPIO_ACTIVE_HIGH &gpioc 27 GPIO_ACTIVE_HIGH >; col-gpios = < /* 列GPIO引脚(包含引脚编号与电平属性) */ &gpioc 16 GPIO_ACTIVE_HIGH &gpioc 17 GPIO_ACTIVE_HIGH &gpioc 18 GPIO_ACTIVE_HIGH &gpioc 19 GPIO_ACTIVE_HIGH >; linux,keymap = < /* 键码映射:格式为<行 列 键值>,需转换为32位数据(行<<24 | 列<<16 | 键值) */ 0x00000074 /* row 0, col 0 */ 0x00010027 /* row 0, col 1 */ 0x0002001c /* row 0, col 2 */ 0x0003006c /* row 0, col 3 */ 0x0100003a /* row 1, col 0 */ 0x0101008b /* row 1, col 1 */ 0x01020067 /* row 1, col 2 */ 0x01030008 /* row 1, col 3 */ 0x02000009 /* row 2, col 0 */ 0x02010010 /* row 2, col 1 */ 0x02020011 /* row 2, col 2 */ 0x02030012 /* row 2, col 3 */ 0x03000013 /* row 3, col 0 */ 0x03010014 /* row 3, col 1 */ 0x03020015 /* row 3, col 2 */ 0x03030016 /* row 3, col 3 */ >; };内核配置的参考
CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_MATRIX=y验证测试的参考
1. 烧录固件后,主控端接入矩阵键盘,正常开机,命令行终端可以输入:`dmesg | grep matrix-keypad`,如下:
# dmesg | grep matrix-keypad [0.873870] input: matrix-keypad as /devices/platform/matrix-keypad/input/input12. 确认输入设备注册状态,命令行终端可以输入:`cat /proc/bus/input/devices`,如下:
# cat /proc/bus/input/devices ... I: Bus=0019 Vendor=0000 Product=0000 Version=0000 N: Name="matrix-keypad" P: Phys= S: Sysfs=/devices/platform/matrix-keypad/input/input1 U: Uniq= H: Handlers=event1 B: PROP=0 B: EV=13 B: KEY=800 101080 0 4000080 107f0300 B: MSC=10 ...3. 使用evtest工具实时监测按键事件上报,验证键值与触发逻辑,如下:
# evtest /dev/input/event1 Input driver version is 1.0.1 Input device ID: bus 0x19 vendor 0x0 product 0x0 version 0x0 Input device name: "matrix-keypad" Supported events: Event type 0 (EV_SYN) Event type 1 (EV_KEY) Event code 8 (KEY_7) Event code 9 (KEY_8) Event code 16 (KEY_Q) Event code 17 (KEY_W) Event code 18 (KEY_E) Event code 19 (KEY_R) Event code 20 (KEY_T) Event code 21 (KEY_Y) Event code 22 (KEY_U) Event code 28 (KEY_ENTER) Event code 39 (KEY_SEMICOLON) Event code 58 (KEY_CAPSLOCK) Event code 103 (KEY_UP) Event code 108 (KEY_DOWN) Event code 116 (KEY_POWER) Event code 139 (KEY_MENU) Event type 4 (EV_MSC) Event code 4 (MSC_SCAN) Properties: Testing ... (interrupt to exit) Event: time 1686704106.478928, type 4 (EV_MSC), code 4 (MSC_SCAN), value 03 Event: time 1686704106.478928, type 1 (EV_KEY), code 108 (KEY_DOWN), value 1 Event: time 1686704106.478928, -------------- SYN_REPORT ------------ Event: time 1686704106.738950, type 4 (EV_MSC), code 4 (MSC_SCAN), value 03 Event: time 1686704106.738950, type 1 (EV_KEY), code 108 (KEY_DOWN), value 0 Event: time 1686704106.738950, -------------- SYN_REPORT ------------常见问题
驱动匹配失败
1. 将检查设备树compatible属性是否与驱动匹配(驱动表为“gpio-matrix-keypad”)。
2. 确认GPIO引脚编号是否正确,是否与其它设备冲突。
3. 查看内核日志(dmesg | grep matrix-keypad),排查资源分配失败原因。
按键无响应
1. 排除硬件的问题,比如按键是否已经损坏或接触不良等。
2. 验证GPIO配置方向:行线为输入、列线为输出,电平属性与硬件一致。
3. 调整DTS配置的`debouce-delay-ms`消抖时间,避免因消抖过短或过长导致检测失败。
4. 检查键码映射配置,确保`linux,keymap`的32位格式正确(行、列、键值未颠倒)。
5. 通过`cat /proc/bus/input/devices`确认输入设备已注册。
按键误触发或重复触发
1. 增大`debounce-delay-ms`消抖延迟(推荐15~20ms,需要根据实际具体硬件调整)。
2. 启用`linux,no-autorepeat`属性,禁止按键自动重复功能。
3. 调整col-scan-delay-us扫描间隔,减少信号串扰导致的误检测。
4. 检查硬件电路,排查GPIO引脚虚焊、供电电源纹波干扰等问题。
无法唤醒系统
1. 确保设备树配置linux,wakeup属性。
2. 验证行GPIO中断支持唤醒功能(设备树中GPIO需要配置wakeup-source属性)。
3. 检查内核电源管理配置,确保中断唤醒功能已启用(CONFIG_PM_SLEEP=y)
键值上报错误
1. 对照Linux标准键码表(linux-x.xx/include/linux/input.h),确保键值定义正确。
2. 检查matrix_keymap_data的keymap数组,确保行列与键值映射对应。
3. 通过evtest工具测试:执行`evtest /dev/input/eventX`(X为输入设备编码),按压按键查看是否上报正确事件。
总结
矩阵键盘,作为一种在MCU或SoC片外设备中常见的键盘布局,其排布类似于矩阵。在电路设计中, 矩阵键盘通过行列式结构优化了MCU或SoC的I/O资源使用,可以满足更多的外部输入需求,可解决单独控制每个按键会消耗大量的IO资源的问题。因此,矩阵键盘一定程度上可有效地节约了资源,常见的矩阵键盘尺寸有4x4和8x8,而其中4x4尺寸的矩阵键盘应用最为广泛。