QMK BMEK 默认键位详解:三层 HHKB 风格 Keymap 的构建与实现
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
BMEK 是一款融合了 HHKB 与 Alice 类键盘优点的紧凑键盘,其默认键位(default keymap)以 HHKB 风格布局为基础,在保留左侧宏功能列和分体式空格键的同时,去掉了左 Shift 的拆分、并将退格与右 Shift 拆分为独立按键。读完本文,你将能够完整理解 keyboards/bemeier/bmek/keymaps/default/README.md 所描述的默认键位方案,掌握make bemeier/bmek/rev3:default的构建方式,并能结合 keymap.c 中的 ASCII 层图,逐层分析 QMK 键位定义的实现细节。
默认键位的设计取舍
BMEK 键盘说明文档 指出,BMEK "combines the best of HHKB & Alice-likes",PCB 与外壳设计均为开源。默认键位的官方描述只有一句话式的概括(见 keymaps/default/README.md):
- 与标准 HHKB 布局相比,默认键位保留了左侧宏功能列(F13–F16 所在的最左一列);
- 保留了分体式空格键(Alice 类布局特征);
- 采用了 HHKB 风格的布局选项:没有拆分的左 Shift(整条左下侧边是一个完整的大 Shift)、拆分的退格键、拆分的右 Shift。
这套取舍直接体现在 keymap.c 使用的LAYOUT_hhkb宏上。info.json 中同时定义了LAYOUT_all与LAYOUT_hhkb两种键位模板:两者物理位置不同之处正是左下侧边——LAYOUT_all中该区域为拆分键(如[3,1]宽 1.25u 与[4,1]分离),而LAYOUT_hhkb中合并为单个 2.25u 的{"matrix": [3, 1], "x": 1.5, "y": 3, "w": 2.25}。默认键位选用后者,因此左 Shift 是一整块按键,右下的右 Shift([3, 13],宽 1.75u)则独立于 Fn 键([3, 14])。
构建默认键位固件
在配置好 QMK 构建环境后,按 BMEK 键盘说明 的命令编译:
# 编译 HHKB 风格布局 + 默认键位 make bemeier/bmek/rev3:default # 如需 VIA 兼容固件 make bemeier/bmek/rev3:via命令中bemeier/bmek/rev3的rev3指 PCB 版本号。仓库下keyboards/bemeier/bmek/同时提供了rev1、rev2、rev3三个版本目录,每个目录内是一个独立的 keyboard.json 构建配置:
- 三个版本的
device_version分别为0.0.1(rev1)、0.0.2(rev2)、0.0.3(rev3); - 各版本的核心差异在
matrix_pins的行列引脚映射上。例如 rev3 的列为["B6", "C6", "C7", "F7", "F6", "F5", "F4", "F0", "B7", "D0", "D1", "D2", "D3", "D5", "D4"],行为["F1", "B4", "B5", "D6", "D7"];而 rev1 的行列引脚完全不同(如 rev1 的列为["F1", "B0", "B1", ...])。因此务必查看自己 PCB 丝印,选择对应 rev 编译,否则矩阵行列错位、按键位置全部错乱。 - 其余构建项三版一致:处理器
atmega32u4,引导加载器atmel-dfu,diode_direction为COL2ROW,并启用bootmagic、extrakey、sleep_led、nkro、rgblight等特性;tapping.term设为 175ms;RGB 灯珠数为 6,WS2812 数据线接E6引脚。
nkro(n-key rollover)特性与 5 行 × 15 列的矩阵规模一致:6 行硬件引脚中有一行(rev3 的行D7参与但布局未用到全部组合)用于容纳最左侧的宏列。
逐层解析默认 Keymap
keymap.c 定义了keymaps数组,共 3 个层,每层都使用LAYOUT_hhkb(...)宏,并在宏参数内以 ASCII 线框图标注了每个物理按键的用途。这种"图 + 码"并置的写法是 QMK 社区维护键位图的可读性实践。
第 0 层:Default 层
线框图(摘自 keymap.c 注释):
┌─────┐ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐ ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐ │ F13 │ │ ESC │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ │ 7 │ 8 │ 9 │ 0 │ - │ = │ \ │ ` │ ├─────┤ ├─────┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┘ ┌─┴───┬─┴───┬─┴───┬─┴───┬─┴───┬─┴───┬─┴───┬─┴─────┤ │ F14 │ │ TAB │ Q │ W │ E │ R │ T │ │ Y │ U │ I │ O │ P │ [ │ ] │ BSPC │ ├─────┤ ├───────┴┬────┴┬────┴┬────┴┬────┴┬────┴┐ └─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴─┬───┴───────┤ │ F15 │ │ CTRL │ A │ S │ D │ F │ G │ │ H │ J │ K │ L │ ; │ ' │ ENTER │ ├─────┤ ├────────┴┬────┴┬────┴┬────┴┬────┴┬────┴┐ ┌┴────┬┴────┬┴────┬┴────┬┴────┬┴────┬┴──────┬────┤ │ F16 │ │ SHFT │ Z │ X │ C │ V │ B │ │ B │ N │ M │ , │ . │ / │ SHFT │ Fn │ └─────┘ └─────────┼─────┼─────┴┬────┴─────┴─────┤ ├─────┴─────┴────┬┴─────┼─────┼─────┴───────┴────┘ │ GUI │ ALT │ SPACE │ │ SPACE/Fn_1 │ ALT │ CTL │ └─────┴──────┴────────────────┘ └────────────────┴──────┴─────┘对应源码为keymaps[0](keymap.c 第 33-37 行)。几个值得注意的映射点:
- 左侧宏列:
KC_F13、KC_F14、KC_F15、KC_F16四个功能键,即 README 所说的 "left macro columns"——它们正是 HHKB 没有、而 BMEK 作为 Alice 类布局保留的左侧额外按键; - 左下角:完整的
KC_LSFT(对应LAYOUT_hhkb中合并的 2.25u 键位[3,1]),随后是分体空格三件套KC_LGUI、KC_LALT、KC_SPC; - 右下角:
LT(1, KC_SPC)是关键设计——该键平时是空格,长按时切入第 1 层(Function Layer 1: Nav),配合独立的KC_RALT、KC_RCTL,构成了 "SPACE/Fn_1" 的复合键; - 右下角 Fn 键:
MO(1),按住不放时临时激活第 1 层,松开即回落到第 0 层。LT与MO是 QMK 中两类常用的层切换键码,分别对应"长按切层 + 短按原键"与"纯按住切层"两种交互模型。
第 1 层:Function Layer 1(导航层)
keymaps[1](keymap.c 第 52-56 行)通过MO(1)(Fn 键)或LT(1, KC_SPC)长按进入,定位为效率导航层:
- F1–F12 功能键行:填补 HHKB 风格主层没有 F 键的缺口,同时右上角保留
KC_INS、KC_DEL; - 编辑/系统键区:
KC_PSCR(截屏)、KC_SCRL(滚动锁)、KC_PAUS(暂停)占据第二行右侧;KC_UP位于第二行,方向键整体落在右半区(KC_HOME、KC_PGUP、KC_LEFT、KC_RGHT、KC_END、KC_PGDN、KC_DOWN); - 音量与媒体:左下区放置
KC_VOLD、KC_VOLU、KC_MUTE、KC_EJCT; - 数字小键盘映射:右侧
KC_PAST(*)、KC_PSLS(/)、KC_PPLS(+)、KC_PMNS(-)借助 ExtraKey 特性把部分键位映射为数字键盘键; - 顶层入口:左上角为
QK_BOOT(对应线框图的 RST,即重启进入固件引导),KC_PWR(电源键)在其右侧;左下角TG(2)可切换(toggle)到第 2 层,实现"导航层内进入配置层"的二级导航。
第 2 层:Firmware Config(RGB 配置层,未完成)
keymaps[2](keymap.c 第 71-75 行)在源码注释中标记为 "TODO",大部分位置为XXXXXXX占位符(QMK 中表示"预留未定义"的键码),目前只有少量 RGB 控制键码可用:
UG_TOGG、UG_NEXT、UG_PREV:开关灯效、切换下/上一个灯效模式;UG_HUEU、UG_HUED:调节色相;UG_SPDU、UG_SPDD:调节灯效速度;UG_SATU、UG_SATD:调节饱和度;UG_VALU、UG_VALD:调节亮度。
这些UG_*键码属于 QMK 的 RGB Underglow 控制键码族,在 quantum/keycodes.h 中定义,并由 quantum/process_keycode/process_quantum.c 统一处理。结合 rev3/keyboard.json 中rgblight.saturation_steps = 8、brightness_steps = 8、led_count = 6的配置,可知这些键码的调节步长由该构建配置决定——饱和度与亮度各只有 8 级台阶,调节按键时以 1/8 的粒度变化。
注意第 2 层的TG(2)位置与第 1 层相同(左下区域同一物理键),从第 0 层进入的路径是:长按空格(LT(1, KC_SPC))或按住 Fn(MO(1))→ 按下TG(2)所在位置切到第 2 层。由于TG是切换型键码,第 2 层会一直生效,再次按下同一物理位置(此时为第 2 层映射)才能切回——从源码结构看,作者将切回入口同样留在了TG(2)对应的键位上,形成自洽的 toggle 循环。
键盘级实现细节
除键位层外,BMEK 的键盘级代码还包含一个电源管理钩子:bmek.c 中的shutdown_kb():
bool shutdown_kb(bool jump_to_bootloader) { if (!shutdown_user(jump_to_bootloader)) { return false; } #ifdef RGBLIGHT_ENABLE rgblight_setrgb(255, 0, 0); #endif return true; }该钩子在键盘关机(或被拉入引导加载器)前执行,先调用shutdown_user()让用户空间有机会否决关机流程;若通过,则在启用RGBLIGHT_ENABLE时把灯效设为红色作为关机指示。这与第 1 层中KC_PWR电源键的用途相呼应:按下电源键触发关机流程,红色灯效提示用户键盘正在进入睡眠/关机。
小结与延伸
- 默认键位文档本身极简,其"图"实际在 keymap.c 的注释中,阅读键位时请以该文件的 ASCII 线框图为准——这一点与 keyboards/bemeier/bmek/readme.md 中 "the keymap shown above may not accurately reflect the default keymap of the firmware" 的提醒一致;
- 布局层面,
LAYOUT_hhkb与LAYOUT_all的完整坐标映射可在 info.json 中核对,两者仅左下侧边结构不同; - 硬件层面,编译前务必确认 PCB 版本(rev1/rev2/rev3),因为 三个 rev 目录的 keyboard.json 中矩阵引脚映射互不相同;
- 若需要运行时修改键位而非重新编译,可编译
make bemeier/bmek/rev3:via使用 VIA 兼容固件,info.json中dynamic_keymap.layer_count声明为 5 层,多于默认键位实际使用的 3 层,为动态重映射留出了余量。
【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考