QMK 固件 Ergo42 客制键盘移植指南:硬件描述、矩阵配置、键帽图层与底光 RGB 实现
2026/9/17 2:26:03 网站建设 项目流程

QMK 固件 Ergo42 客制键盘移植指南:硬件描述、矩阵配置、键帽图层与底光 RGB 实现

【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware

Ergo42 是一款 7x4 正交(ortholinear)分离式(split)客制机械键盘,其 QMK 固件移植位于 keyboards/biacco42/ergo42/。本篇基于该键盘的官方说明文档与仓库内的实际源码,完整讲解它的硬件架构、keyboard.json数据驱动配置、换手(swap hands)机制、默认键帽图层的分层设计,以及带底光(underglow)键帽中 RGB 灯效的自定义实现,帮助你在 QMK 框架下理解并复刻一个小型分离式正交键盘的完整移植。

键盘概览

根据 readme.md,Ergo42 的核心信息如下:

  • 键盘定位:split 7x4 ortholinear keyboard(左右两半,每半 4 行 x 7 列,共 56 个矩阵位置,实际为 42 键布局的分离正交键盘);
  • 主控硬件:Ergo42 PCB + Pro Micro(ATmega32u4);
  • 键盘维护者:Biacco42;
  • 固件构建(搭建好 QMK 构建环境后):
make biacco42/ergo42/rev1:default:flash

命令含义是:针对biacco42/ergo42键盘的rev1硬件版本,编译default键帽并直接烧录(flash)。若只想编译不烧录,可去掉:flash后缀。

rev1 硬件描述:keyboard.json 数据驱动配置

当前版本的 QMK 采用数据驱动方式描述硬件,核心文件是 rev1/keyboard.json。它声明了 USB 参数、特性开关、矩阵引脚、布局坐标等全部硬件事实,逐项解析如下:

USB 标识与功能开关

"usb": { "vid": "0xBC42", "pid": "0x0042", "device_version": "1.0.0" }, "features": { "bootmagic": false, "mousekey": true, "extrakey": true, "command": true }
  • vid0xBC42pid0x0042——两个值都取自“42”这个数字,与键盘名字呼应;
  • bootmagic关闭,即不提供 Bootloader Magic 功能(用特定按键组合进入 bootloader 的硬件级能力);
  • 默认启用mousekeyextrakey(多媒体键、系统键所需)与command(QMK 控制台命令)三个特性。

矩阵引脚与二极管方向

"matrix_pins": { "cols": ["F5", "F6", "F7", "B1", "B3", "B2", "B6"], "rows": ["D7", "E6", "B4", "B5"] }, "diode_direction": "COL2ROW"

每半边由 4 根行线(D7E6B4B5)和 7 根列线(F5F6F7B1B3B2B6)组成 4x7 的行列矩阵;COL2ROW表示二极管方向为列到行,即列线主动驱动、行线读取。QMK 在分离键盘上会把左右两半各 4 行合并为一个 8 行 x 7 列的虚拟矩阵(左半占用 row 0–3,右半占用 row 4–7),这也是后续布局文件中右半键位出现[4, x][7, x]行号的来源。

分离通信与 WS2812 底光

"split": { "enabled": true, "serial": { "pin": "D0" } }, "ws2812": { "pin": "D3" }, "development_board": "promicro"
  • split.enabled: trueserial.pin: "D0"表示启用分离键盘的 UART 串口通信协议,左右半通过D0引脚直连收发——这是 QMK 中“简单分离键盘”最轻量的互联方式(另一侧 Pro Micro 通过D0/D1交叉连接);
  • ws2812.pin: "D3"声明底光 WS2812 灯串的驱动引脚;配套的rgblight.led_count: 12声明灯串有 12 颗 LED;
  • development_board: "promicro"指定使用 Pro Micro 开发板配置,决定工具链、时钟等底层参数。

布局别名与 4x14 坐标

"layout_aliases": { "LAYOUT": "LAYOUT_ortho_4x14" }, "layouts": { "LAYOUT_ortho_4x14": { "layout": [ {"matrix": [0, 0], "x": 0, "y": 0}, ... ] } }

LAYOUT被别名为LAYOUT_ortho_4x14,键帽代码里写LAYOUT(...)实际展开的就是这个布局宏。layout数组把 56 个矩阵坐标映射到 4 行 x 15 列宽(x: 0–14)的二维平面:左半占据 x=0–6,右半占据 x=8–14,x=7 的间隙正是两半之间的物理分割线(split 间距)。值得注意的细节是右半的坐标是镜像排布的——例如第一行右半依次是[4,6][4,5][4,0],即矩阵列号从 6 递减到 0,这样键盘右侧的物理布局与左侧对称,符合右手使用习惯。

换手支持:ergo42.c 中的 hand_swap_config

分离键盘常见的特性是MO(SWAP_H)——按下后左右手功能互换。QMK 的换手逻辑依赖一张hand_swap_config位置映射表,Ergo42 在 ergo42.c 中提供了一个 weak 定义:

#ifdef SWAP_HANDS_ENABLE __attribute__ ((weak)) const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { {{0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}}, {{0, 5}, {1, 5}, {2, 5}, {3, 5}, {5, 5}, {5, 5}, {6, 5}}, /* ... 共 8 行 ... */ {{0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}}, }; #endif

这张 8x7 的表把每个矩阵坐标映射为“换手后该按下事件应该对应的位置”。从表格结构看,它把 row 0–3(左半)与 row 4–7(右半)整体互换,实现左半按下时按右半的位置处理、反之亦然。该定义标记了__attribute__((weak)),意味着默认使用此表,用户空间可以给出同名强符号覆盖它。

底层调用关系可以在 quantum/action.c 中印证:按键事件分发时,若启用了换手,事件坐标会先通过查表转换:

// quantum/action.c 中的关键调用 event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col);

只有在编译时定义SWAP_HANDS_ENABLE(键帽rules.mk中写SWAP_HANDS_ENABLE = yes)时这段逻辑才会参与编译,ergo42.c中的配置表也才生效。

默认键帽:三层图层的正交布局

默认键帽 keymaps/default/keymap.c 定义了 4 个图层常量,但实际实现了 3 层:

#define BASE 0 #define META 1 #define SYMB 2 #define GAME 3

GAME仅声明未实现,从源码结构看是作者预留的图层编号。

BASE 层

,------------------------------------------------. ,------------------------------------------------. | ESC | Tab | Q | W | E | R | T | | Y | U | I | O | P | [ | Bksp | |------+------+------+------+------+------+------| |-------------+------+------+------+------+------| | Del | RCtrl| A | S | D | F | G | | H | J | K | L | ; | ] | Enter| |------+------+------+------+------+------+------| |------|------+------+------+------+------+------| | SYMB | LSft | Z | X | C | V | B | | N | M | , | . | / | UP | RSft | |------+------+------+------+------+------+------| |------+------+------+------+------+------| | LGUI | LCtrl| ` | \ | LAlt | META |Space | |Space | ' | - | = | LEFT | DOWN | RIGHT| `------------------------------------------------' `------------------------------------------------'
[BASE] = LAYOUT( KC_ESC, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_BSPC, KC_DEL, KC_RCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_RBRC, KC_ENT, MO(SYMB), KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_UP, KC_RSFT, KC_LGUI, KC_LCTL, KC_GRV, KC_BSLS, KC_LALT, MO(META), KC_SPC, KC_SPC, KC_QUOT, KC_MINS, KC_EQL, KC_LEFT, KC_DOWN, KC_RGHT ),

几个值得注意的设计点:

  • 由于是 7x4 的正交布局没有专门的功能键行,方向键被“借用”到了左右两角的下两行:左半底行左起第 5–7 键与右半底行右起第 3–1 键(KC_LEFTKC_DOWNKC_RGHT),KC_UP在右半第三行;
  • 使用MO(SYMB)MO(META)作为图层切换键:按住时对应按键按修饰键语义处理(这里是透传),同时切换到对应图层。MO不产生额外的修饰键状态,避免了普通LSFT(T(...))写法可能带来的修饰键残留问题;
  • 两半最内侧各放一个KC_SPC,方便双手拇指快速输入空格。

META 层

[META] = LAYOUT( QK_BOOT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_LBRC, KC_RBRC, KC_6, KC_7, KC_8, KC_9, KC_0, _______, _______, KC_F1, XXXXXXX, KC_INT5, KC_INT4, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, XXXXXXX, XXXXXXX, _______, _______, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, S(KC_LBRC), S(KC_RBRC), KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX ),

META 层集中了数字行、F1–F12、花括号、方向键,左上角放QK_BOOT(一键进入 bootloader,方便更新固件)。该层还体现了 QMK 的国际化键码:KC_INT5KC_INT4分别表示 ISO 键盘中位于5´位置的键,适配不同 ANSI/ISO 键帽。

SYMB 层

[SYMB] = LAYOUT( _______, S(KC_1), S(KC_2), S(KC_3), S(KC_4), S(KC_5), KC_LBRC, KC_RBRC, S(KC_6), S(KC_7), S(KC_8), S(KC_9), S(KC_0), _______, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, S(KC_9), S(KC_0), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, S(KC_LBRC), S(KC_RBRC), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ )

SYMB 层通过S(KC_x)(Shift + 键码)提供! @ # $ % ^ & * ( )等符号,未定义的位置统一用_______(透传)或XXXXXXX(无操作)填充。

底光键帽:default-underglow 的 RGB 实现

Ergo42 支持 WS2812 底光,仓库提供了专门的 keymaps/default-underglow/ 键帽,由三个文件构成:

1. rules.mk:开启 RGBLIGHT 特性

RGBLIGHT_ENABLE = yes

这是 QMK 键帽级的特性开关。开启后固件才会编译 RGB 灯效代码,对应的 make 命令变为:

make biacco42/ergo42/rev1:default-underglow:flash

2. config.h:自定义 LED 数量与灯效集

config.h 中:

// Underglow #undef RGBLIGHT_LED_COUNT #define RGBLIGHT_LED_COUNT 14 // Number of LEDs #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL #define RGBLIGHT_EFFECT_SNAKE #define RGBLIGHT_EFFECT_KNIGHT #define RGBLIGHT_EFFECT_CHRISTMAS #define RGBLIGHT_EFFECT_STATIC_GRADIENT #define RGBLIGHT_EFFECT_RGB_TEST #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLIGHT_SLEEP
  • #undef再重新定义RGBLIGHT_LED_COUNT为 14——注意这里覆盖了 keyboard.json 中声明的led_count: 12,说明实际灯串按 14 颗配置;
  • 每个RGBLIGHT_EFFECT_xxx宏对应一种可切换的灯效模式,最终可通过RGB_MOD键循环;
  • RGBLIGHT_SLEEP让键盘在睡眠状态下自动关灯省电。

3. keymap.c:RGB 控制层与自定义灯效键

default-underglow/keymap.c 在 BASE/META/SYMB 三层之上增加了第 4 层 RGB 层,BASE 层左下角改为MO(RGB)进入:

[RGB] = LAYOUT( XXXXXXX, ..., XXXXXXX, ..., UG_TOGG, UG_HUEU, UG_SATU, UG_VALU, TAP_ANIM, XXXXXXX, _______, ..., UG_NEXT, UG_HUED, UG_SATD, UG_VALD, RGB_RST, XXXXXXX, ... )

该层提供了完整的 QMK 标准 RGB 控制键:

键码作用
UG_TOGG开/关底光
UG_NEXT切换下一个灯效模式
UG_HUEU/UG_HUED色相 +/−
UG_SATU/UG_SATD饱和度 +/−
UG_VALU/UG_VALD亮度 +/−

此外自定义了两个键码:

enum custom_keycodes { RGB_RST = SAFE_RANGE, TAP_ANIM };
  • RGB_RST:按下时调用eeconfig_update_rgblight_default()rgblight_enable(),把 RGB 配置恢复为固件默认值并重新点亮;
  • TAP_ANIM:作者自定义的“按一次变一次”的呼吸式色相动画。其实现是每次按键事件都调用rgblight_mode_noeeprom(1)(强制使用 Breathing 灯效但不写 EEPROM),并将色相相对上次推进 5 度:
if (isTapAnim) { rgblight_mode_noeeprom(1); uint16_t hue = (rgblight_config.hue + 5) % 360; rgblight_sethsv_noeeprom(hue, rgblight_config.sat, rgblight_config.val); }

这段逻辑放在process_record_user钩子中,rgblight_mode_noeeprom/rgblight_sethsv_noeeprom_noeeprom后缀保证动画只改运行态、不落盘,从而不污染用户已保存的 RGB 配置——这是 QMK RGB API 中一个典型的“临时效果”用法。

构建与定制要点小结

  1. 编译烧录make biacco42/ergo42/rev1:default:flash(默认键帽)或make biacco42/ergo42/rev1:default-underglow:flash(带底光);
  2. 硬件事实以 keyboard.json 为准:矩阵引脚、COL2ROW方向、split 串口D0、WS2812D3、Pro Micro 开发板,全部由 rev1/keyboard.json 声明;
  3. 换手功能:需在键帽rules.mk中开启SWAP_HANDS_ENABLE,并可使用 ergo42.c 提供的 weak 版hand_swap_config作为默认左右互换表;
  4. 布局镜像LAYOUT_ortho_4x14中右半矩阵列号递减,是分离正交键盘保证左右对称的关键细节,在自定义布局时容易踩坑;
  5. RGB 定制:LED 数量、可用灯效集合在config.h中按编译期宏控制,运行时控制则完全复用 QMK 的UG_*标准键码与rgblight_*API。

这套“keyboard.json描述硬件 + 薄 C 文件补充 weak 默认值 + 键帽目录承载行为”的结构,正是 QMK 当前小型客制键盘移植的标准范式,Ergo42 是一个麻雀虽小五脏俱全的参考样本。

【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询