拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

深入解析 ZMK 的 Makerdiary M60 60% ANSI 键盘 Shield:矩阵配线与按键映射实战

深入解析 ZMK 的 Makerdiary M60 60% ANSI 键盘 Shield:矩阵配线与按键映射实战
  • 固件
  • 嵌入式
  • 智能硬件
  • 蓝牙

【免费下载链接】zmk

ZMK Firmware Repository

项目地址:https://gitcode.com/gh_mirrors/zm/zmk
点击查看免费下载

导读

本篇文章以 ZMK 固件仓库中 m60 Shield 的官方 README 为核心骨架,结合其完整的 overlay 设备树、keymap 按键映射 与 Kconfig 构建配置,系统讲解如何为一个基于 MakerDiary M.2 nRF52840 模块的 60% ANSI 键盘定义矩阵扫描、物理布局与分层按键行为。读完本文,你将掌握 ZMK Shield 从硬件接线到固件配置的完整落地路径,并理解矩阵变换(matrix transform)与物理布局(physical layout)的协作原理,可直接参照为自己的键盘编写 ZMK 配置。

M60 Shield 是什么

M60 是由 MakerDiary(官方产品页 目录下,配套的核心硬件特性在 README 中被概括为三点:

  • Per key RGB LED:每键独立的 RGB 背光;
  • 使用 MakerDiary M.2 nRF52840 模块:主控为 M.2/NGFF 封装形式的 nRF52840 无线 SoC 模块,同时支持 USB 与 BLE 输出;
  • 矩阵布线(Matrix wiring):按键采用标准行列矩阵扫描结构。

从元数据文件 m60.zmk.yml 可以确认该 Shield 的依赖关系与能力声明:

file_format: "1" id: m60 name: MakerDiary m60 type: shield url: https://makerdiary.com/pages/m60-mechanical-keyboard requires: [makerdiary_nrf52840_m2] features: - keys - studio

其中requires: [makerdiary_nrf52840_m2]表示它必须搭载 MakerDiary nRF52840 M.2 模块(interconnect),而features中的studio表明该 Shield 还支持 ZMK Studio 的运行时键位编辑能力。

硬件的官方资料入口

README 将硬件的详细规格(如 PCB 原理图、引脚定义、走线细节)指向了 MakerDiary 官方 Wiki 的硬件开发者指南(https://wiki.makerdiary.com/m60/developer_guide/hardware/)。在 ZMK 仓库内,我们无法获得 PCB 层面的完整图纸,但可以通过 m60.overlay 精确反推出固件视角下真实的 GPIO 接线方案——这正是下一节要深入讲解的内容。

矩阵扫描配置:从硬件走线到设备树

8×8 矩阵与 col2row 二极管方向

m60.overlay 中定义了kscan0扫描节点:

kscan0: kscan { compatible = "zmk,kscan-gpio-matrix"; wakeup-source; diode-direction = "col2row"; row-gpios = <&gpio0 5 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio0 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio0 7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio0 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio1 9 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio1 8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio0 12 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> , <&gpio0 11 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)> ; col-gpios = <&gpio0 19 GPIO_ACTIVE_HIGH> , <&gpio0 20 GPIO_ACTIVE_HIGH> , <&gpio0 21 GPIO_ACTIVE_HIGH> , <&gpio0 22 GPIO_ACTIVE_HIGH> , <&gpio0 23 GPIO_ACTIVE_HIGH> , <&gpio0 24 GPIO_ACTIVE_HIGH> , <&gpio0 25 GPIO_ACTIVE_HIGH> , <&gpio0 26 GPIO_ACTIVE_HIGH> ; };

解读要点如下:

  • 8 行 × 8 列:row-gpios与col-gpios各有 8 个引脚,构成 64 个矩阵交点,恰好覆盖 60% 布局的 61 个按键;
  • diode-direction = "col2row":二极管从列指向行,扫描时行作为输入、列作为输出;
  • 行引脚启用GPIO_PULL_DOWN:行端在未按下时被拉低,按下时变为高电平,配合GPIO_ACTIVE_HIGH即可稳定识别触发,同时配置了wakeup-source允许按键唤醒设备;
  • 跨 GPIO 控制器:行信号分布在gpio0与gpio1两个端口上,列信号全部位于gpio0,这反映了 PCB 走线对引脚分配的约束,也是编写其他键盘 overlay 时需要注意的细节。

矩阵变换:把物理行列映射为逻辑按键位置

矩阵扫描得到的是"行列坐标",而键位图需要的是一维的"按键位置编号"。default_transform节点(compatible = "zmk,matrix-transform")负责完成这层转换,声明了columns = <8>; rows = <8>;并通过map将矩阵坐标逐一映射到按键盘物理排列的序号:

default_transform: keymap_transform_0 { compatible = "zmk,matrix-transform"; columns = <8>; rows = <8>; map = < RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5) RC(0,6) RC(0,7) RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5) RC(3,3) RC(3,2) RC(3,1) RC(3,0) RC(2,7) RC(2,6) RC(2,5) RC(2,4) RC(2,3) RC(2,2) RC(2,1) RC(2,0) RC(1,7) RC(1,6) RC(3,4) RC(3,5) RC(3,6) RC(3,7) RC(4,0) RC(4,1) RC(4,2) RC(4,3) RC(4,4) RC(4,5) RC(4,6) RC(4,7) RC(5,0) RC(6,4) RC(6,3) RC(6,2) RC(6,1) RC(6,0) RC(5,7) RC(5,6) RC(5,5) RC(5,4) RC(5,3) RC(5,2) RC(5,1) RC(6,5) RC(6,6) RC(6,7) RC(7,0) RC(7,1) RC(7,2) RC(7,3) RC(7,4) >; };

RC(row, col)是矩阵变换头文件 matrix_transform.h 提供的宏,含义是"矩阵第 row 行、第 col 列"。从映射顺序可以直观看出:

  • 行 0、行 1 的前几列承载主键区;
  • 左 Shift、Caps Lock 等大键被分配到如RC(3,3)、RC(3,4)等"对角线"上的矩阵交点,这是 PCB 为绕开走线冲突而做的矩阵压缩设计;
  • 空格键(6.25U)只占用RC(7,0)一个交点,符合单键单交点的常规做法。

复用官方 60% ANSI 物理布局

M60 没有重新定义按键的物理尺寸与坐标,而是直接复用了 ZMK 仓库内置的 60percent/ansi.dtsi 物理布局,并通过chosen与 transform 完成装配:

/ { chosen { zmk,kscan = &kscan0; zmk,physical-layout = &layout_60_ansi; }; }; &layout_60_ansi { transform = <&default_transform>; };
  • zmk,kscan指向kscan0扫描节点;
  • zmk,physical-layout指向layout_60_ansi,该布局在 ansi.dtsi 中定义了 61 个按键的物理尺寸(1U、1.5U、2U、6.25U 空格等)与坐标,并为每颗按键标注了display-name = "60% ANSI";
  • transform = <&default_transform>将矩阵坐标桥接到物理布局的按键序号。

这种"官方通用物理布局 + 私有矩阵变换"的组合,是 ZMK 生态中常见的做法:物理形状交给通用模板,矩阵压缩逻辑留在各 Shield 自己的 overlay 中,职责清晰、便于维护。

按键映射:默认层与 Fn 层的实战设计

m60.keymap 展示了完整的键位图。它引入了三个头文件:

#include <behaviors.dtsi> #include <dt-bindings/zmk/keys.h> #include <dt-bindings/zmk/bt.h>
  • behaviors.dtsi 提供&kp(按键按下)、&mo(瞬时层)、&trans(透传)、&bootloader、&sys_reset、&bt、&none等行为;
  • keys.h 定义 HID 键值宏(N1、Q、LSHFT等);
  • bt.h 定义蓝牙行为参数(BT_CLR、BT_SEL 0等)。

默认层:标准 60% ANSI 键位

默认层布局与 README 描述的 60% ANSI 完全一致:字母区、数字区、修饰键,且保留了 Windows 风格的空格行(LCTRL / LGUI / LALT / SPACE / RALT / MO(1) / RGUI / RCTRL)。关键行如下:

&kp ESC &kp N1 ... &kp MINUS &kp EQUAL &kp BSPC &kp TAB &kp Q ... &kp LBKT &kp RBKT &kp BSLH &kp CLCK &kp A ... &kp SEMI &kp SQT &kp RET &kp LSHFT &kp Z ... &kp COMMA &kp DOT &kp FSLH &kp RSHFT &kp LCTRL &kp LGUI &kp LALT &kp SPACE &kp RALT &mo 1 &kp RGUI &kp RCTRL

&mo 1是唯一的非普通按键:按住进入 Fn 层,松开即退出,属于瞬时层行为。bindings 数组的书写顺序必须与物理布局中按键的物理排列顺序一一对应,任何错位都会导致按键错乱。

Fn 层:功能键、蓝牙与系统控制

第二层fn_layer(display-name = "Fn Layer")演示了 ZMK 多层键位图的典型玩法,共四类用法:

  1. 功能键行:F1 ~ F12与GRAVE(波浪号~);
  2. 系统级行为:&bootloader(进入刷写模式)与&sys_reset(软件重启);
  3. 蓝牙配置:&bt BT_CLR(清除配对信息)、&bt BT_SEL 0至&bt BT_SEL 4(在 5 个 BLE profile 间切换选择),这些参数由 bt.h 定义,对应 ZMK 的多 profile 蓝牙架构;
  4. 导航与透传:&kp LEFT / DOWN / UP / RIGHT方向键,以及大量&trans透传——按下 Fn 层中标记为&trans的位置时,行为会继续沿用默认层对应键的绑定,这是分层键位图中避免重复声明常用键的标准手法。&none则用于显式屏蔽某键在 Fn 层的功能。
&kp GRAVE &kp F1 ... &kp F12 &bootloader &trans &bt BT_CLR &none ... &sys_reset &trans &bt BT_SEL 0 &bt BT_SEL 1 &bt BT_SEL 2 &bt BT_SEL 3 &bt BT_SEL 4 &kp LEFT &kp DOWN &kp UP &kp RIGHT &none &none &trans &trans &none ... &trans &trans &trans &trans &trans &trans &trans &trans &trans

注意 Fn 层最后一行全部是&trans,这意味着 Fn+空格等组合仍会透传到底层绑定,行为符合直觉。

构建集成:Kconfig 与元数据

Kconfig.shield 与默认键盘名

m60 目录下的两个 Kconfig 文件负责把 Shield 接入 Zephyr 构建系统:

  • Kconfig.shield:config SHIELD_M60通过$(shields_list_contains,m60)在构建时检测是否选择了 m60 Shield;
  • Kconfig.defconfig:当SHIELD_M60使能时,将ZMK_KEYBOARD_NAME默认设为"m60",从而决定 BLE 广播与 USB 描述符中显示的设备名称。

主控与互联的依赖链

m60 依赖的makerdiary_nrf52840_m2interconnect 定义在 app/boards/interconnects/makerdiary_nrf52840_m2/makerdiary_nrf52840_m2.zmk.yml,其描述指出该 M.2 模块通过 M.2/NGFF 封装暴露大量 GPIO,可灵活挂接 I2C、SPI 等外设;而实际主控板则由 app/boards/makerdiary/nrf52840_m2 目录下的nrf52840_m2//zmk板定义提供(arch: arm,输出支持usb与ble)。因此 M60 的完整依赖链是:

Board: nRF52840 M.2 (nrf52840_m2//zmk) └─ Interconnect: makerdiary_nrf52840_m2 └─ Shield: m60

使用与构建方式

要基于本仓库构建 M60 固件,可按标准 ZMK 构建流程操作:确保已按 docs/development/local-toolchain 中的说明配置好 Zephyr SDK 与 west 环境后,在 app 目录执行类似如下的构建命令:

west build -b makerdiary_nrf52840_m2 -- -DSHIELD=m60

构建产物可通过 USB 或 BLE 刷写到 M.2 模块上。之后即可:

  • 通过修改 m60.keymap 自定义各层键位;
  • 通过调整 m60.overlay 中的row-gpios/col-gpios与default_transform适配自定义接线;
  • 利用features: studio元数据启用 ZMK Studio,在运行时通过上位机直接编辑键位。

小结

M60 Shield 是 ZMK 中"官方硬件 + 社区固件"协作的典型样本:README 只给出了硬件概貌与外部资料入口,真正的技术细节沉淀在 overlay(8×8 矩阵扫描 + 矩阵压缩变换)、keymap(默认层 + Fn 层的分层设计)、Kconfig(构建集成)与元数据(依赖与能力声明)四类文件中。对自研键盘开发者而言,这套"矩阵压缩 + 物理布局复用 + 分层键位"的组合模式,正是从 PCB 走线约束走向可用固件的最短路径,值得在同类项目中直接借鉴。

  • 固件
  • 嵌入式
  • 智能硬件
  • 蓝牙

【免费下载链接】zmk

ZMK Firmware Repository

项目地址:https://gitcode.com/gh_mirrors/zm/zmk
点击查看免费下载

相关推荐

上一篇:推荐开源项目:noise——打造去中心化应用的高效P2P网络栈
下一篇:Termux-MiUnlock常见问题解决:7个最常见错误及修复方法

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

返回列表