QMK 开源静电电容数字键盘 EC 23U:构建、刷写与源码级解析
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
本篇技术指南围绕 QMK 固件仓库中 keyboards/cipulot/ec_23u 的 EC 23U 数字键盘展开,系统讲解这款开源静电电容(Electrostatic Capacitive,简称 EC)数字键盘的硬件背景、构建与刷写流程、进入 Bootloader 的两种方式,并结合仓库内配置与驱动源码剖析其电容矩阵扫描、自适应触发(APC)与快速触发(Rapid Trigger)等核心实现原理。读完本文,你将能够独立完成 EC 23U 的固件编译、烧录与按键阈值调校,并理解 QMK 自定义矩阵在 EC 键盘上的落地方式。
一、项目概览:什么是 EC 23U
EC 23U 是 cipulot 维护的一款开源静电电容数字键盘 PCB(Open source numpad Electrostatic Capacitive PCB)。与常规机械键盘的物理触点导通不同,EC 键盘通过测量按键电容变化来判定按下与释放,其按键手感与触发方式具有明显差异,因此固件侧的处理逻辑也完全不同。
在 QMK 仓库中,EC 23U 的完整工程位于 keyboards/cipulot/ec_23u,其目录结构如下:
keyboards/cipulot/ec_23u/ ├── keymaps/ │ └── default/ │ └── keymap.c # 默认键位 ├── config.h # 矩阵、AMUX、APC 阈值等配置 ├── halconf.h # ChibiOS HAL 配置 ├── keyboard.json # 键盘描述与构建选项 ├── mcuconf.h # MCU 配置 ├── post_rules.mk # 引入 cipulot 公共 EC 驱动 ├── readme.md # 项目说明 └── rules.mk # 编译优化选项基础信息(来源 keyboard.json):
| 项目 | 值 |
|---|---|
| 键盘名称 | EC 23U |
| 制造商 / 维护者 | Cipulot |
| 主控 | STM32F401 |
| Bootloader | stm32-dfu |
| USB VID / PID | 0x6369 / 0x6B95 |
| 二极管方向 | COL2ROW |
| 矩阵规模 | 4 行 × 6 列(见 config.h) |
| 布局 | LAYOUT_all、LAYOUT_numpad_6x4 |
此外,keyboard.json 开启了如下功能:NKRO、鼠标键(mousekey)、多媒体扩展键(extrakey)、控制台(console)、RGB 灯光(rgblight,21 颗 LED,数据引脚 B5),以及数字锁定指示灯(num_lock,引脚 B14);构建层面启用了 LTO 链接时优化,rules.mk 中指定OPT = 2优化级别。
二、构建环境与固件编译
与 QMK 其他键盘一致,EC 23U 使用标准 QMK 构建流程。首先需要完成 QMK 构建环境配置(包括工具链、编译依赖与 QMK CLI),然后即可使用make命令编译固件。
在仓库根目录下执行以下命令即可构建默认键位固件:
make cipulot/ec_23u:default其中cipulot/ec_23u为目标键盘路径,default为键位名(对应 keymaps/default/keymap.c)。
编译产物为可直接刷写的固件文件,之后通过 DFU 方式烧录到板载 STM32F401:
make cipulot/ec_23u:default:flash带:flash目标会先编译,再调用对应的刷写工具(stm32-dfu)将固件写入主控。关于构建工具安装与 make 指令的完整说明,可参考仓库文档 docs/getting_started_make_guide.md 与 docs/newbs.md;对 QMK 完全陌生的用户,建议先阅读 docs/newbs_getting_started.md 完成环境搭建。
注意:EC 23U 属于 EC 键盘,其矩阵依赖模拟量采样而非 GPIO 扫描,因此普通机械键盘的构建方式仅覆盖了 CLI 层面,固件内部的处理逻辑完全不同(详见下文源码解析)。
默认键位速览
默认键位位于 keymaps/default/keymap.c,采用双层布局:
- 第 0 层(主层):完整的数字键盘功能,包括
KC_NUM、KC_PSLS(/)、KC_PAST(*)、KC_PMNS(-)、KC_PPLS(+)、KC_PENT、KC_P0~KC_P9、KC_PDOT,以及KC_ESC、KC_TAB、KC_BSPC和进入功能层的MO(1)。 - 第 1 层(功能层):通过
MO(1)按住触发,包含 RGB 控制(UG_TOGG开关、UG_VALD/UG_VALU亮度调节)、NKRO 切换NK_TOGG,以及关键的系统复位键QK_BOOT——按下它即可让键盘进入 DFU Bootloader,无需拆壳短接。
[1] = LAYOUT_all( UG_TOGG, UG_VALD, UG_VALU, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, QK_BOOT, _______)三、进入 Bootloader 的两种方式
EC 23U 支持两种进入 Bootloader 的方式(见 readme.md):
- 物理复位(Physical reset):短接 PCB 顶部的暴露焊盘(Long short the exposed pads on the top of the PCB)。这是最可靠的硬性方式,适用于固件异常、键位未映射
QK_BOOT等场景。 - 键位触发(Keycode in layout):按下布局中映射到
QK_BOOT的按键。默认键位的第 1 层已预置QK_BOOT(位于右下区域),可在不拆机的情况下进入 DFU 模式。
两种方式最终都将使 STM32F401 进入 stm32-dfu 引导模式,此时即可通过make cipulot/ec_23u:default:flash或 DFU 工具刷写固件。
四、源码级解析:EC 键盘的电容矩阵驱动
EC 23U 的固件价值不仅在于数字键盘功能本身,更在于其完整的 EC 电容矩阵驱动实现。这类键盘不使用普通二极管矩阵,而是通过模拟多路复用器(AMUX)逐列选通、对电容充放电并采样 ADC 电压值来判断按键状态。
4.1 驱动装配方式
post_rules.mk 引入了 cipulot 全系列 EC 键盘的公共驱动:
include keyboards/cipulot/common/common_cipulot.mk而 common_cipulot.mk 完成了关键装配:
CUSTOM_MATRIX = lite ANALOG_DRIVER_REQUIRED = yes VPATH += keyboards/cipulot/common SRC += matrix.c ec_board.c ec_switch_matrix.cCUSTOM_MATRIX = lite:声明使用自定义矩阵实现,替代默认 GPIO 矩阵扫描;ANALOG_DRIVER_REQUIRED = yes:启用 ADC 模拟量驱动,这是电容采样所必需的;SRC追加的matrix.c、ec_board.c、ec_switch_matrix.c分别承担自定义矩阵入口、板级引脚初始化和 EC 采样算法。
4.2 自定义矩阵初始化与扫描
matrix.c 是 QMK 自定义矩阵的接入点:
void matrix_init_custom(void) { ec_init(); // 初始化 EC 相关引脚与 AMUX ec_noise_floor(); // 启动时采样噪声底 } bool matrix_scan_custom(matrix_row_t current_matrix[]) { return ec_matrix_scan(current_matrix); }两个细节值得注意:
- 启动噪声底采样:开机时会调用
ec_noise_floor()采集每个键位的环境噪声水平,作为后续阈值判定的基准,避免不同环境下误触发。 - Bootmagic 被覆盖:同文件中
bootmagic_scan()被重写为空实现,注释明确指出这是为了避免与 EC 矩阵逻辑冲突(EC 键盘的模拟量采集与 Bootmagic 的启动时按键检测机制不兼容)。因此该键盘在 keyboard.json 中也将bootmagic功能关闭。
4.3 矩阵与模拟前端配置
config.h 定义了 EC 23U 的完整硬件映射:
#define MATRIX_ROWS 4 #define MATRIX_COLS 6 #define MATRIX_ROW_PINS \ { B13, B12, A7, B0 } #define AMUX_COUNT 1 #define AMUX_MAX_COLS_COUNT 6 #define AMUX_EN_PINS \ { C15 } #define AMUX_SEL_PINS \ { C14, C13, B6 } #define AMUX_COL_CHANNELS_SIZES \ { 6 } #define AMUX_0_COL_CHANNELS \ { 4, 6, 3, 2, 0, 1 } #define DISCHARGE_PIN A3 #define ANALOG_PORT A2- 行引脚(ROW)直接由 MCU 引脚驱动,用于对列电容充电;
- 列信号通过 1 片模拟多路复用器(AMUX)选通,
AMUX_SEL_PINS(C14、C13、B6)为通道选择线,AMUX_EN_PINS(C15)为使能引脚; AMUX_0_COL_CHANNELS = { 4, 6, 3, 2, 0, 1 }表示 6 个物理列在 AMUX 上的通道编号顺序(注意并非递增排列,PCB 走线决定了这种映射);DISCHARGE_PIN(A3)用于放电,ANALOG_PORT(A2)用于 ADC 采样。
典型的 EC 键位采样流程(对应ec_switch_matrix.h中声明的discharge_capacitor()、charge_capacitor()、select_amux_channel()等函数)为:先放电 → 选中目标列 → 对该列充电 → 经 ADC 读取电压 → 依据阈值判定该键是否按下。
4.4 触发模式与 APC / Rapid Trigger 配置
EC 键盘的灵魂在于触发判定。根据 ec_switch_matrix.h 中的配置结构体,EC 23U 支持三种触发模式(actuation_mode):
| 模式 | 含义 |
|---|---|
| 0 | 整板统一的自适应触发(APC),按固定阈值判定按下/释放 |
| 1 | 快速触发(Rapid Trigger),基于整板统一的触发点做增量判定 |
| 2 | 快速触发,基于按键静止点(resting point)做增量判定 |
config.h中的默认阈值如下:
#define DEFAULT_ACTUATION_MODE 0 #define DEFAULT_MODE_0_ACTUATION_LEVEL 550 // 模式 0 按下阈值 #define DEFAULT_MODE_0_RELEASE_LEVEL 500 // 模式 0 释放阈值 #define DEFAULT_MODE_1_INITIAL_DEADZONE_OFFSET DEFAULT_MODE_0_ACTUATION_LEVEL #define DEFAULT_MODE_1_ACTUATION_OFFSET 70 // 模式 1/2 按下偏移 #define DEFAULT_MODE_1_RELEASE_OFFSET 70 // 模式 1/2 释放偏移 #define DEFAULT_EXTREMUM 1023 #define EXPECTED_NOISE_FLOOR 0 #define NOISE_FLOOR_THRESHOLD 50 #define BOTTOMING_CALIBRATION_THRESHOLD 100 #define DEFAULT_NOISE_FLOOR_SAMPLING_COUNT 30 #define DEFAULT_BOTTOMING_READING 1023 #define DEFAULT_CALIBRATION_STARTER true #define DISCHARGE_TIME 10关键设计点:
- 模式 0(APC):ADC 读数低于
actuation(550)视为按下,回升超过release(500)视为释放,形成回差(hysteresis)防止抖动。 - 模式 1/2(Rapid Trigger):不依赖绝对阈值,而是以触发点为基准计算偏移(
actuation_offset/release_offset,范围 1–255),实现快速连打时更灵敏的响应;DEFAULT_EXTREMUM(1023)为 ADC 满量程参考值。 - 按键触底校准:
bottoming_calibration相关字段支持逐键记录触底读数(bottoming_reading),用于将阈值按每颗键的实际行程重标定(rescale()函数),从而在按键个体差异下保持一致手感。
由于运行时配置需要持久化,config.h将键盘级 EEPROM 数据区大小设为:
#define EECONFIG_KB_DATA_SIZE 57而 ec_switch_matrix.h 通过编译期断言强制eeprom_ec_config_t结构体大小与之一致:
_Static_assert(sizeof(eeprom_ec_config_t) == EECONFIG_KB_DATA_SIZE, "Mismatch in keyboard EECONFIG stored data");这保证了在键位固件升级、重新刷写后,用户的触发阈值等校准数据仍能可靠地保存在片内 EEPROM 中。若使用 VIA(VIA_ENABLE),common_cipulot.mk 还会额外编译via_ec.c,让用户可以通过 VIA 图形界面直接调整每颗键的触发阈值。
五、扩展与后续学习
EC 23U 并非 cipulot 唯一的 EC 键盘。在 keyboards/cipulot 目录下还有大量同类产品(如ec_60、ec_65x、ec_980c、ec_tkl等),它们共享common_cipulot.mk中的同一套 EC 驱动,仅通过各自的config.h区分矩阵规模、AMUX 通道与默认阈值,非常适合对照阅读以理解 EC 键盘驱动的通用设计。
若希望进一步深入,建议按以下路径学习:
- keyboards/cipulot/common/ec_switch_matrix.h:理解三种触发模式与阈值结构体;
- keyboards/cipulot/common/ec_switch_matrix.c:阅读充放电、ADC 采样与状态机判定实现;
- keyboards/cipulot/common/ec_board.c:了解行/列引脚与 AMUX 的板级初始化;
- docs/features 下的 QMK 功能文档,了解 NKRO、RGB、自定义矩阵等特性的标准用法。
至此,你已掌握 EC 23U 从编译刷写到电容触发原理的完整链路:make cipulot/ec_23u:default:flash一条命令完成构建与烧录,短接焊盘或QK_BOOT键进入 DFU,APC 与 Rapid Trigger 阈值则可在源码中按需调校,并通过 EEPROM 持久化保存。
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考