在上一篇文章中已經完成鍵盤的 Layout,這篇文章將會接續製作步驟的第 3 步——生成並編輯 QMK 韌體。
本篇是以發文當時最新的
0.27.5
版本的 QMK 作為示範。如果你想要切換 QMK 版本的話,可以使用下面的方法(需要先安裝好 QMK MSYS 環境與 Git)。
- 打開 QMK MSYS
- 移到 QMK 工作目錄:
qmk cd
- 更新 Repo:
git fetch --all --tags --prune
- 切換指定版本:
git checkout tags/<VERSION>
,其中<VERSION>
替換成目標版本。例如git checkout tags/0.27.5
- 可以忽略提示「detached HEAD」狀態。
- 確認:
git status
。可能會看到類似HEAD detached at 0.27.5
的回應,就代表目前已經切換到0.27.5
版了。
準備環境
首先要準備 QMK 環境,現在這一步已經相當簡單。請執行以下步驟:
- 下載並執行 QMK MSYS 工具。
- 在 QMK MSYS 中輸入並執行指令
qmk setup
指令。 - 過程中它可能會請你確認一些問題,基本上只要回答
y
即 yes 就好。首次設定會有一步是 Clone repo,這個步驟是把整個 QMK 的檔案從 GitHub 上下載下來,所以會需要一段時間。
完成後會有一行 QMK is ready to go
。往上滾動一些會看到一行 Repo version: x.y.z
,x.y.z
代表目前的 QMK 版本。
準備好環境後,可以先編譯其它鍵盤作為測試。在 QMK MSYS 中執行:
qmk compile -kb clueboard/66/rev3 -km default
若環境沒問題的話,稍微等待後你應該會看到一排 [OK]
,及類似這樣的結尾:
Linking: .build/clueboard_66_rev3_default.elf [OK]
Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK]
Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK]
Checking file size of clueboard_66_rev3_default.hex [OK]
* The firmware size is fine - 26356/28672 (2316 bytes free)
QMK 的檔案預設會在:C:/Users/<USERNAME>/qmk_firmware
。上面這個訊息中的 .build/clueboard_66_rev3_default.hex
代表的就是 C:/Users/<USERNAME>/qmk_firmware/.build/clueboard_66_rev3_default.hex
。
環境建立好後就可以編輯一些設定了。如何選擇微控制器 MCU 一文中已經說明了如何挑選適合的 MCU,這時你應該已經決定好要用什麼 MCU 來製作了。
如果你對嵌入式不是很熟悉的話,我只推薦 RP2040 和 ATmega32U4(Pro Micro),而 RP2040 是我目前認爲製作 QMK 鍵盤的首選,因爲它價格便宜、性能很好、功能完善、空間充足、購買方便、使用者也多。如果沒有特殊原因的話建議使用 RP2040。以下將分別介紹 RP2040 和 Pro Micro 的步驟。
RP2040
創建新鍵盤
在 QMK MSYS 中執行:
qmk new-keyboard
這時你可能會看到這樣的回應:
Generating a new QMK keyboard directory
Name Your Keyboard Project
For more infomation, see:
https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject
Keyboard Name?
這時請輸入你想要的鍵盤名稱後按 Enter,例如我使用「0_my_kb_rp2040」做示範。命名規則請參考 Naming Your Keyboard/Project。名稱以「0」開頭單純是因爲名稱排序下比較好找資料夾。
再來它回問你 Username 及 Real Name,這部分就打你自己想要的名稱即可(之後也還可以改),例如我兩者都打「ziteh」。
Attribution
Used for maintainer, copyright, etc
Your GitHub Username? [ziteh]
More Attribution
Used for maintainer, copyright, etc
Your Real Name? [ziteh]

接著會問你基礎佈局,你可以選一個和你預計要做的鍵盤較為類似的佈局,這樣後續要改的東西就會比較少。例如常見的 60% 鍵盤為「11. 65_ansi」,那就輸入其編號「11」後按 Enter。我這裡就選擇「none of the above」表示不使用現成的特定 Layout。
實際編號可能會因爲版本而不同,請以選項名稱和你看到的為主。
然後會問你是否使用現成的開發板「Using a Development Board?」,對於 RP2040 即使你確實是使用現成的開發板,我也建議在這裡回答「n」以使用基於 MCU 的設定,這樣如果未來你的鍵盤想要變更不同的 RP2040 開發板也不會需要修改 GPIO,靈活度會比較高。
最後會問你所使用的 MCU(Microcontroller),這裡就選擇「RP2040」。

完成後會顯示類似這樣的訊息:
Created a new keyboard called 0_my_kb_rp2040.
Build Command: qmk compile -kb 0_my_kb_rp2040 -km default.
Project Location: C:/Users/<USERNAME>/qmk_firmware/keyboards/0_my_kb_rp2040.
Now update the config files to match the hardware!
這樣我們的新鍵盤就在 QMK 的目錄底下建立完成了。接下來要打開我們剛剛建立的鍵盤檔案,為細部功能做調整。
使用文字編輯器(例如我使用 VS Code)打開剛剛建立的新鍵盤的資料夾。QMK 預設的路徑是在 C:\Users\<USERNAME>\qmk_firmware\
,而我們剛剛建立的鍵盤在其中的 keyboards\0_my_kb_rp2040\
。
這時你應該會看到 0_my_kb_rp2040
下有這些檔案:
keymaps\
default\
keymap.c
keyboard.json
readme.md
修改 keyboard.json
這是最主要的設定檔(也就是舊版的 info.json
),大部分的設定都在這裡調整。有關它的詳細說明請參考 info.json Format 及 Data Driven Configuration。以下各個項目無需按照順序,請以名稱為主,但是在編輯時要注意 JSON 禁止尾逗號。
舊版 QMK 在
rules.mk
和config.h
中的設定現在多數都移到keyboard.json
中了。
鍵盤資訊
keyboard_name
:鍵盤名稱。這裡目前是剛剛輸入的0_my_kb_rp2040
。這個無強硬格式規範。manufacturer
:製造商,通常可以打你的名字。maintainer
:維護者,通常可以打你的名字。url
:可以填該鍵盤的相關說明網址。可以留空。
MCU 與 Bootloader
MCU 與 Bootloader 的設定是要互相配合的,要依照你使用的 MCU 來選擇正確的 Bootloader。
首先看到 processor
的部分,這裡要選擇使用的 MCU。由於我們剛剛選擇的是 RP2040,所以這裡目前是 RP2040
沒錯,如果你使用的是別的 MCU 就請修改。QMK 支援的 MCU 可以參考 Compatible Microcontrollers。
再來是 bootloader
的部分,由於我們是 RP2040,所以這裡要是 rp2040
。如果你使用的是不同的 MCU,那 bootloader 也要改。這裡有個簡單的對照表:
微控制器/開發板 | Bootloader |
---|---|
Pro Micro | caterina |
RP2040 | rp2040 |
Teensy | halfkay |
Atmel DFU | atmel-dfu |
LUFA DFU | lufa-dfu |
QMK DFU | qmk-dfu |
ATmega328P | usbasploader |
QMK 支援的微控制器和 Bootloader 很多,如果是上面沒有寫到的話,請自行參考 QMK 文件。更詳細的說明可以看 Flashing Instructions and Bootloader Information 。
功能
features
中可以設定要啓用的功能,像是 nkro
是 N 鍵防衝突(USB N-Key Rollover),mousekey
是滑鼠按鍵支援。更詳細的設定請參考 Config Options。
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
USB
usb
底下會設定一些 USB 相關的資料。有 vid
、pid
及 device_version
這三個,分別代表 Vendor ID、Product ID 和 Device version,vid
,pid
為十六進制數值。可以保持不變,也可以改成自己喜歡的。官方文件請參考 USB。
USB VID 與 PID 是 USB 設備的識別號,正常來說是要向 USB 協會申請/購買,但是我們只是要自己做鍵盤的話通常都自行設定就好。要注意的是,如果一臺電腦同時接了多個相同 VID 和 PID 的裝置,那這些裝置可能無法運作。
例如:
"usb": {
"vid": "0xC1ED",
"pid": "0x23B0",
"device_version": "1.0.0"
}
佈局 Layouts
一把鍵盤可以設定多個佈局(Layout),但這裡我們就僅簡單示範單一佈局。官方文件請參考 Layout Format。
LAYOUT
就是我們目前的佈局名稱,內部的 layout
就是要設定每一個按鍵的位置,包含了物理上的實際位置和在鍵矩陣中的行列位置。
看其中兩個鍵:
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
matrix
是設定該鍵在「鍵掃描矩陣」中的行列位置,格式為 [row, col]
。x
和 y
是設定該鍵的「物理」位置,也就是它的鍵軸/鍵帽實際擺在哪裡。另外還有 w
與 h
可以設定鍵帽的寬度和高度,label
可以設定名稱。
layout
的內容可以透過一些工具來幫忙,就不用完全自己手打。打開 Convert KLE raw to QMK info.json 頁面,並將上一篇文章 最後的 Raw data 複製並貼到裡面就可以轉換。
例如我貼上:
["Num Lock","/","*","-"],
["7\nHome","8\n↑","9\nPgUp",{h:2},"+"],
["4\n←","5","6\n→"],
["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"],
[{w:2},"0\nIns",".\nDel"]
轉換後會得到:
{
"keyboard_name": "",
"url": "",
"maintainer": "qmk",
"layouts": {
"LAYOUT": {
"layout": [
{"label":"Num Lock", "x":0, "y":0},
{"label":"/", "x":1, "y":0},
{"label":"*", "x":2, "y":0},
{"label":"-", "x":3, "y":0},
{"label":"7", "x":0, "y":1},
{"label":"8", "x":1, "y":1},
{"label":"9", "x":2, "y":1},
{"label":"+", "x":3, "y":1, "h":2},
{"label":"4", "x":0, "y":2},
{"label":"5", "x":1, "y":2},
{"label":"6", "x":2, "y":2},
{"label":"1", "x":0, "y":3},
{"label":"2", "x":1, "y":3},
{"label":"3", "x":2, "y":3},
{"label":"Enter", "x":3, "y":3, "h":2},
{"label":"0", "x":0, "y":4, "w":2},
{"label":".", "x":2, "y":4}
]
}
}
}
可以發現轉換出來的 layout
就是我們要的格式,將它複製到我們的 keyboard.json
中(注意階層要看準,括號有多有少都會出錯。我通常會直接複製並取代方括號 []
的內容)。
但是它還是缺少了 matrix
的資料,這部分我們要自己手動打。matrix
的部分我還沒找到比較好的方式可以自動產生,所以目前就只能自己手打,稍微有點麻煩。
如果你不太知道 matrix
的座標要怎麼打的話,可以使用 Keyboard Firmware Builder,將 上一篇文章 最後的 Raw data 複製並貼到裡面。

在標籤頁「Wiring」裡,你看到的是鍵盤的鍵矩陣接線圖。它會自動幫你生成一個可行的接線方式,如果你不喜歡的話也可以手動修改。


它提供的接線圖就很清楚地表達了每個鍵的鍵矩陣位置,請以此為依據來編輯每個鍵的 matrix
內容。
修改完成後:
"layouts": {
"LAYOUT": {
"layout": [
{"label": "NumLock", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "/", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "*", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "-", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "7", "matrix": [1, 0], "x": 0, "y": 1},
{"label": "8", "matrix": [1, 1], "x": 1, "y": 1},
{"label": "9", "matrix": [1, 2], "x": 2, "y": 1},
{"label": "4", "matrix": [2, 0], "x": 0, "y": 2},
{"label": "5", "matrix": [2, 1], "x": 1, "y": 2},
{"label": "6", "matrix": [2, 2], "x": 2, "y": 2},
{"label": "+", "matrix": [2, 3], "x": 3, "y": 1, "h": 2},
{"label": "1", "matrix": [3, 0], "x": 0, "y": 3},
{"label": "2", "matrix": [3, 1], "x": 1, "y": 3},
{"label": "3", "matrix": [3, 2], "x": 2, "y": 3},
{"label": "0", "matrix": [4, 1], "x": 0, "y": 4, "w": 2},
{"label": ".", "matrix": [4, 2], "x": 2, "y": 4},
{"label": "Enter", "matrix": [4, 3], "x": 3, "y": 3, "h": 2}
]
}
}
這一步可能比較複雜,要多看幾次比對。
注意這裡
matrix
設定的鍵矩陣行列大小要和下面的matrix_pins
中的cols
與rows
數量是一致的。
鍵矩陣
一般來說,鍵盤的按鍵數都大於微控制器的 GPIO 接腳數,所以會使用鍵盤矩陣掃描(Keyboard Matrix Scanning)技術。如果不是很懂鍵盤矩陣掃描的話,最好先找一些資料瞭解一下,這裡就不贅述。
diode_direction
表示鍵矩陣硬體的二極體方向,一般都是使用COL2ROW
。matrix_pins
設定鍵矩陣的各個腳位。這邊同時決定了鍵矩陣的大小和實際的腳位為何。
由於我們是使用 RP2040,雖然有很多不同的 RP2040 開發板,但它的原始腳位名稱都是 GPxx
。這時只要選擇你需要的 GPIO 腳即可。
例如如果你用的是 KB2040,那就是看下圖中黃色的名稱,其中 GPIO2
代表 GP2
、GPIO10
代表 GP10
。

又或者你用的是 RP2040-Zero,那就是看下圖的綠色的名稱。

例如我可以這樣設定:
"diode_direction": "COL2ROW",
"matrix_pins": {
"cols": ["GP2", "GP3", "GP4", "GP5"],
"rows": ["GP29", "GP28", "GP27", "GP26", "GP22"]
},
如果你沒有使用微控制器的經驗,或是不知道要選哪個腳位才行,只要你的鍵盤沒有要加什麼特別的功能(如螢幕、搖桿、可條亮度的 LED 或分離式鍵盤)的話,基本上使用任何腳位都可以。如果你的鍵盤有這些需要特殊硬體功能(UART、SPI、I²C、PWM)的話,記得保留,不要被矩陣掃描佔用了。
這部分的官方文件請參考 Matrix Pins。
修改完成
完成的完整 keyboard.json
大概長這樣:
{
"$schema": "https://raw.githubusercontent.com/qmk/qmk_firmware/refs/heads/master/data/schemas/keyboard.jsonschema",
"keyboard_name": "0_my_kb_rp2040",
"manufacturer": "ziteh",
"maintainer": "ziteh",
"url": "",
"processor": "RP2040",
"bootloader": "rp2040",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0xFEED"
},
"matrix_pins": {
"cols": ["GP2", "GP3", "GP4", "GP5"],
"rows": ["GP29", "GP28", "GP27", "GP26", "GP22"]
},
"layouts": {
"LAYOUT": {
"layout": [
{ "label": "NumLock", "matrix": [0, 0], "x": 0, "y": 0 },
{ "label": "/", "matrix": [0, 1], "x": 1, "y": 0 },
{ "label": "*", "matrix": [0, 2], "x": 2, "y": 0 },
{ "label": "-", "matrix": [0, 3], "x": 3, "y": 0 },
{ "label": "7", "matrix": [1, 0], "x": 0, "y": 1 },
{ "label": "8", "matrix": [1, 1], "x": 1, "y": 1 },
{ "label": "9", "matrix": [1, 2], "x": 2, "y": 1 },
{ "label": "4", "matrix": [2, 0], "x": 0, "y": 2 },
{ "label": "5", "matrix": [2, 1], "x": 1, "y": 2 },
{ "label": "6", "matrix": [2, 2], "x": 2, "y": 2 },
{ "label": "+", "matrix": [2, 3], "x": 3, "y": 1, "h": 2 },
{ "label": "1", "matrix": [3, 0], "x": 0, "y": 3 },
{ "label": "2", "matrix": [3, 1], "x": 1, "y": 3 },
{ "label": "3", "matrix": [3, 2], "x": 2, "y": 3 },
{ "label": "0", "matrix": [4, 1], "x": 0, "y": 4, "w": 2 },
{ "label": ".", "matrix": [4, 2], "x": 2, "y": 4 },
{ "label": "Enter", "matrix": [4, 3], "x": 3, "y": 3, "h": 2 }
]
}
}
}
你會注意到我這裡多了一行 $schema
,這個是用來設定這個 JSON 的欄位格式。如果你是使用 VS Code 的話還會有自動補全和提示的功能。假如你怕自己編輯 JSON 檔案的格式或拼字有錯,可以多加這行,讓文字編輯器幫你做檢查,不然不加也可以,不會影響 QMK 的功能。
修改 keymap.c
keymaps
資料夾內可以放多種不同的鍵映射(Keymap),但是至少有有一個名為 default
的預設 Keymap。現在已經自動產生這個預設 keymap 了。打開 keymaps\default\keymap.c
。
這裡要修改的是 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {}
的內容,也就是 Keymap。Keymap 的結構與行列數量必須要與剛剛在 keyboard.json
中設定的 layout
中的 matrix
對應。
這裡要手動修改的話也是有一點麻煩,所以一樣推薦使用 Keyboard Firmware Builder,將 上一篇文章 最後的 Raw data 複製並貼到裡面。到最後一個標籤頁「Compile」按下「Download .zip」按鈕來儲存它產生的 QMK 韌體原始檔(舊版)。

將下載的 .zip
檔解壓縮,打開其中的 qmk_firmware\keyboards\kb\keymaps\default\keymap.c
。你會看到和我們所需要的 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {}
的內容,可以把複製到我們的鍵盤的 keymap.c
中。
不過它的每一個層的名稱是 KEYMAP()
,而我們剛剛產生的名稱是 LAYOUT
,所以這邊也要一同改成 LAYOUT()
。
LAYOUT()
中的這些就代表了鍵盤各個鍵位的按鍵功能。像是 KC_P7
代表了 Numpad7(數字鍵盤的 7),而詳細的按鍵名稱請參考 QMK 的說明文件:Keycodes Overview。
你所需要做的就是把該按鍵的代號(如 KC_P7
)放在對的位置就好了,之後你按下這個位置的按鍵就會是輸出這個鍵值。QMK 鍵盤支援多層 Keymap 設定,而每一塊 [n] = LAYOUT()
代表的是一層,最上面的是第 0 層,往下是第 1、2…n 層。
修改完的 keymap.c
大概長這樣:
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format off
[0] = LAYOUT(
KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
KC_P7, KC_P8, KC_P9,
KC_P4, KC_P5, KC_P6, KC_PPLS,
KC_P1, KC_P2, KC_P3,
KC_P0, MO(1), KC_PENT
),
[1] = LAYOUT(
_______, _______, _______, _______,
KC_HOME, KC_UP, KC_PGUP,
KC_LEFT, _______, KC_RGHT, _______,
KC_END, KC_DOWN, KC_PGDN,
KC_INS, _______, KC_DEL
)};
// clang-format on
有些人可能會喜歡加上一些圖案:
[0] = LAYOUT(
// ┌────────┬─────────┬──────────┬─────────┐
KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
// ├────────┼─────────┼──────────┼─────────┤
KC_P7, KC_P8, KC_P9,
// ├────────┼─────────┼──────────┤ │
KC_P4, KC_P5, KC_P6, KC_PPLS,
// ├────────┼─────────┼──────────┼─────────┤
KC_P1, KC_P2, KC_P3,
// ├────────┴─────────┼──────────┤ │
KC_P0, MO(1), KC_PENT
// └──────────────────┴──────────┴─────────┘
),
clang-format off
與clang-format on
是讓 VS Code 的 Clang-format 格式化工具不用美化該區域的內容,和功能無關可以不加。如果你稍微懂一點 C 語言的話,
LAYOUT()
就是是#define
巨集 Macro。
修改 config.h
原始建立的檔案中沒有這個檔案,我們自行新增即可,放在和 keyboard.json
同一個層級。
我們要在 config.h
中加入一行 #define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
來啓用 Double-tap Reset,未來燒錄要進入 Bootloader 模式只要雙擊 Reset 就好會比較方便。
#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET
Pro Micro (ATmega32U4)
創建新鍵盤
在 QMK MSYS 中執行:
qmk new-keyboard
這時你可能會看到這樣的回應:
Generating a new QMK keyboard directory
Name Your Keyboard Project
For more infomation, see:
https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject
Keyboard Name?
這時請輸入你想要的鍵盤名稱後按 Enter,例如我使用「0_my_kb_promicro」做示範。命名規則請參考 Naming Your Keyboard/Project。名稱以「0」開頭單純是因爲名稱排序下比較好找資料夾。
再來它回問你 Username 及 Real Name,這部分就打你自己想要的名稱即可(之後也還可以改),例如我兩者都打「ziteh」。
Attribution
Used for maintainer, copyright, etc
Your GitHub Username? [ziteh]
More Attribution
Used for maintainer, copyright, etc
Your Real Name? [ziteh]

接著會問你基礎佈局,你可以選一個和你預計要做的鍵盤較為類似的佈局,這樣後續要改的東西就會比較少。例如常見的 60% 鍵盤為「11. 65_ansi」,那就輸入其編號「11」後按 Enter。我這裡就選擇「none of the above」表示不使用現成的特定 Layout。
實際編號可能會因爲版本而不同,請以選項名稱和你看到的為主。
然後會問你是否使用現成的開發板「Using a Development Board?」,這裡回答「y」,然後它會再問你用的是什麼開發板,回答「promicro」。

完成後會顯示類似這樣的訊息:
Created a new keyboard called 0_my_kb_promicro.
Build Command: qmk compile -kb 0_my_kb_promicro -km default.
Project Location: C:/Users/<USERNAME>/qmk_firmware/keyboards/0_my_kb_promicro.
Now update the config files to match the hardware!
這樣我們的新鍵盤就在 QMK 的目錄底下建立完成了。接下來要打開我們剛剛建立的鍵盤檔案,為細部功能做調整。
使用文字編輯器(例如我使用 VS Code)打開剛剛建立的新鍵盤的資料夾。QMK 預設的路徑是在 C:\Users\<USERNAME>\qmk_firmware\
,而我們剛剛建立的鍵盤在其中的 keyboards\0_my_kb_promicro\
。
這時你會看到 0_my_kb_promicro
下有這些檔案:
keymaps\
default\
keymap.c
keyboard.json
readme.md
修改 keyboard.json
這是最主要的設定檔(也就是舊版的 info.json
),大部分的設定都在這裡調整。有關它的詳細說明請參考 info.json Format 及 Data Driven Configuration。以下各個項目無需按照順序,請以名稱為主,但是在編輯時要注意 JSON 禁止尾逗號。
舊版 QMK 在
rules.mk
和config.h
中的設定現在多數都移到keyboard.json
中了。
鍵盤資訊
keyboard_name
:鍵盤名稱。這裡目前是剛剛輸入的0_my_kb_promicro
。這個無強硬格式規範。manufacturer
:製造商,通常可以打你的名字。maintainer
:維護者,通常可以打你的名字。url
:可以填該鍵盤的相關說明網址。可以留空。
開發板
MCU 與 Bootloader 的設定是要互相配合的,要依照你使用的 MCU 來選擇正確的 Bootloader。但是由於我們已經選擇使用開發板 "development_board": "promicro"
所以應該不會有什麼問題,也不用設定 processor
和 bootloader
。
特別說明一下,Pro Micro 的 MCU 是 ATmega32U4,而它的 Bootloader 基本上是
caterina
。很久以前我在學習 QMK 時因爲 Bootloader 選錯所以一直失敗,如果你在使用 Pro Micro 遇到了一些問題的話,可能可以試試明確指定"bootloader": "caterina"
。
這裡簡單的整理了一些 MCU 和 Bootloader 的對應表作爲參考。
微控制器/開發板 | Bootloader |
---|---|
Pro Micro | caterina |
RP2040 | rp2040 |
Teensy | halfkay |
Atmel DFU | atmel-dfu |
LUFA DFU | lufa-dfu |
QMK DFU | qmk-dfu |
ATmega328P | usbasploader |
QMK 支援的微控制器和 Bootloader 很多,如果是上面沒有寫到的話,請自行參考 QMK 文件。更詳細的說明可以看 Flashing Instructions and Bootloader Information 。
功能
features
中可以設定要啓用的功能,像是 nkro
是 N 鍵防衝突(USB N-Key Rollover),mousekey
是滑鼠按鍵支援。更詳細的設定請參考 Config Options。
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
USB
usb
底下會設定一些 USB 相關的資料。有 vid
、pid
及 device_version
這三個,分別代表 Vendor ID、Product ID 和 Device version,vid
,pid
為十六進制數值。可以保持不變,也可以改成自己喜歡的。官方文件請參考 USB。
USB VID 與 PID 是 USB 設備的識別號,正常來說是要向 USB 協會申請/購買,但是我們只是要自己做鍵盤的話通常都自行設定就好。要注意的是,如果一臺電腦同時接了多個相同 VID 和 PID 的裝置,那這些裝置可能無法運作。
例如可以使用(vid
,pid
為十六進制數值):
"usb": {
"vid": "0xC1ED",
"pid": "0x23B0",
"device_version": "1.0.0"
}
佈局 layouts
一把鍵盤可以設定多個佈局(Layout),但這裡我們就僅簡單示範單一佈局。官方文件請參考 Layout Format。
LAYOUT
就是我們目前的佈局名稱,內部的 layout
就是要設定每一個按鍵的位置,包含了物理上的實際位置和在鍵矩陣中的行列位置。
看其中兩個鍵:
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
matrix
是設定該鍵在「鍵掃描矩陣」中的行列位置,格式為 [row, col]
。x
和 y
是設定該鍵的「物理」位置,也就是它的鍵軸/鍵帽實際擺在哪裡。另外還有 w
與 h
可以設定鍵帽的寬度和高度,label
可以設定名稱。
layout
的內容可以透過一些工具來幫忙,就不用完全自己手打。打開 Convert KLE raw to QMK info.json 頁面,並將上一篇文章 最後的 Raw data 複製並貼到裡面就可以轉換。
例如我貼上:
["Num Lock","/","*","-"],
["7\nHome","8\n↑","9\nPgUp",{h:2},"+"],
["4\n←","5","6\n→"],
["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"],
[{w:2},"0\nIns",".\nDel"]
轉換後會得到:
{
"keyboard_name": "",
"url": "",
"maintainer": "qmk",
"layouts": {
"LAYOUT": {
"layout": [
{"label":"Num Lock", "x":0, "y":0},
{"label":"/", "x":1, "y":0},
{"label":"*", "x":2, "y":0},
{"label":"-", "x":3, "y":0},
{"label":"7", "x":0, "y":1},
{"label":"8", "x":1, "y":1},
{"label":"9", "x":2, "y":1},
{"label":"+", "x":3, "y":1, "h":2},
{"label":"4", "x":0, "y":2},
{"label":"5", "x":1, "y":2},
{"label":"6", "x":2, "y":2},
{"label":"1", "x":0, "y":3},
{"label":"2", "x":1, "y":3},
{"label":"3", "x":2, "y":3},
{"label":"Enter", "x":3, "y":3, "h":2},
{"label":"0", "x":0, "y":4, "w":2},
{"label":".", "x":2, "y":4}
]
}
}
}
可以發現轉換出來的 layout
就是我們要的格式,將它複製到我們的 keyboard.json
中(注意階層要看準,括號有多有少都會出錯。我通常會直接複製並取代方括號 []
的內容)。
但是它還是缺少了 matrix
的資料,這部分我們要自己手動打。matrix
的部分我還沒找到比較好的方式可以自動產生,所以目前就只能自己手打,稍微有點麻煩。
如果你不太知道 matrix
的座標要怎麼打的話,可以使用 Keyboard Firmware Builder,將 上一篇文章 最後的 Raw data 複製並貼到裡面。

在標籤頁「Wiring」裡,你看到的是鍵盤的鍵矩陣接線圖。它會自動幫你生成一個可行的接線方式,如果你不喜歡的話也可以手動修改。


它提供的接線圖就很清楚地表達了每個鍵的鍵矩陣位置,請以此為依據來編輯每個鍵的 matrix
內容。
修改完成後:
"layouts": {
"LAYOUT": {
"layout": [
{"label": "NumLock", "matrix": [0, 0], "x": 0, "y": 0},
{"label": "/", "matrix": [0, 1], "x": 1, "y": 0},
{"label": "*", "matrix": [0, 2], "x": 2, "y": 0},
{"label": "-", "matrix": [0, 3], "x": 3, "y": 0},
{"label": "7", "matrix": [1, 0], "x": 0, "y": 1},
{"label": "8", "matrix": [1, 1], "x": 1, "y": 1},
{"label": "9", "matrix": [1, 2], "x": 2, "y": 1},
{"label": "4", "matrix": [2, 0], "x": 0, "y": 2},
{"label": "5", "matrix": [2, 1], "x": 1, "y": 2},
{"label": "6", "matrix": [2, 2], "x": 2, "y": 2},
{"label": "+", "matrix": [2, 3], "x": 3, "y": 1, "h": 2},
{"label": "1", "matrix": [3, 0], "x": 0, "y": 3},
{"label": "2", "matrix": [3, 1], "x": 1, "y": 3},
{"label": "3", "matrix": [3, 2], "x": 2, "y": 3},
{"label": "0", "matrix": [4, 1], "x": 0, "y": 4, "w": 2},
{"label": ".", "matrix": [4, 2], "x": 2, "y": 4},
{"label": "Enter", "matrix": [4, 3], "x": 3, "y": 3, "h": 2}
]
}
}
這一步可能比較複雜,要多看幾次比對。
注意這裡
matrix
設定的鍵矩陣行列大小要和下面的matrix_pins
中的cols
與rows
數量是一致的。
鍵矩陣
一般來說,鍵盤的按鍵數都大於微控制器的 GPIO 接腳數,所以會使用鍵盤矩陣掃描(Keyboard Matrix Scanning)技術。如果不是很懂鍵盤矩陣掃描的話,最好先找一些資料瞭解一下,這裡就不贅述。
diode_direction
表示鍵矩陣硬體的二極體方向,一般都是使用COL2ROW
。matrix_pins
設定鍵矩陣的各個腳位。這邊同時決定了鍵矩陣的大小和實際的腳位為何。
要注意的是,開發板上標示的接腳名稱可能不是微控制器的原始腳位名稱,而在 QMK 中只使用 MCU 的原始腳位名稱。
請參考下圖,Pro Micro 開發板上的 D16
(綠色) 其實是 ATmega32U4 的 PB2
(藍紫色),在 QMK 中要打 B2
。如果是 D2
(綠色)腳的話,它的原始腳位是 PD1
(藍紫色),所以 QMK 中要打 D1
。這邊小心不要搞混了,簡單來說就是要看藍紫色的腳位。

例如我可以這樣設定:
"diode_direction": "COL2ROW",
"matrix_pins": {
"cols": [ "D1", "D0", "D4", "C6" ],
"rows": [ "F4", "F5", "F6", "F7", "B1" ]
},
如果你沒有使用微控制器的經驗,或是不知道要選哪個腳位才行,只要你的鍵盤沒有要加什麼特別的功能(如螢幕、搖桿、可條亮度的 LED 或分離式鍵盤)的話,基本上使用任何腳位都可以。如果你的鍵盤有這些需要特殊硬體功能(UART、SPI、I²C、PWM)的話,記得保留,不要被矩陣掃描佔用了。
PB2、PD7…的 P 是指 Port,通常以 8 或 16 腳為一個 Port。P 後面的英文字為 Port 名,通常由 A 開始。再來的數字是腳位編號,通常由 0 開始。所以 PB2 就代表 Port-B 的 2 號腳,也就是 Port-B 的第 3 支接腳,因為 Port-B 的第一支腳是 PB0。 使用現成的開發板(像是 Pro Micro)的話,記得要選有引出的接腳(開發板可能不會把微控制器的所有接腳都拉出)。
這部分的官方文件請參考 Matrix Pins。
LTO
LTO 是 Link-Time Optimization(連接時間最佳化)的意思,它可以幫助減少最終燒錄檔案的大小。由於 ATmega32U4 的 ROM 容量真的很小,可能功能開多一點就爆錶了,所以一般來說會建議開啓這個功能。更多減少燒錄檔大小的說明請參考:Squeezing the most out of AVR
"build": {
"lto": true
},
在舊版 QMK 中,這個設定是在
rules.mk
中的LTO_ENABLE = yes
。
修改完成
完成的完整 keyboard.json
大概長這樣:
{
"$schema": "https://raw.githubusercontent.com/qmk/qmk_firmware/refs/heads/master/data/schemas/keyboard.jsonschema",
"keyboard_name": "0_my_kb_promicro",
"manufacturer": "ziteh",
"maintainer": "ziteh",
"url": "",
"development_board": "promicro",
"diode_direction": "COL2ROW",
"features": {
"bootmagic": true,
"command": false,
"console": false,
"extrakey": true,
"mousekey": true,
"nkro": true
},
"build": {
"lto": true
},
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0xFEED"
},
"matrix_pins": {
"cols": ["D1", "D0", "D4", "C6"],
"rows": ["F4", "F5", "F6", "F7", "B1"]
},
"layouts": {
"LAYOUT": {
"layout": [
{ "label": "NumLock", "matrix": [0, 0], "x": 0, "y": 0 },
{ "label": "/", "matrix": [0, 1], "x": 1, "y": 0 },
{ "label": "*", "matrix": [0, 2], "x": 2, "y": 0 },
{ "label": "-", "matrix": [0, 3], "x": 3, "y": 0 },
{ "label": "7", "matrix": [1, 0], "x": 0, "y": 1 },
{ "label": "8", "matrix": [1, 1], "x": 1, "y": 1 },
{ "label": "9", "matrix": [1, 2], "x": 2, "y": 1 },
{ "label": "4", "matrix": [2, 0], "x": 0, "y": 2 },
{ "label": "5", "matrix": [2, 1], "x": 1, "y": 2 },
{ "label": "6", "matrix": [2, 2], "x": 2, "y": 2 },
{ "label": "+", "matrix": [2, 3], "x": 3, "y": 1, "h": 2 },
{ "label": "1", "matrix": [3, 0], "x": 0, "y": 3 },
{ "label": "2", "matrix": [3, 1], "x": 1, "y": 3 },
{ "label": "3", "matrix": [3, 2], "x": 2, "y": 3 },
{ "label": "0", "matrix": [4, 1], "x": 0, "y": 4, "w": 2 },
{ "label": ".", "matrix": [4, 2], "x": 2, "y": 4 },
{ "label": "Enter", "matrix": [4, 3], "x": 3, "y": 3, "h": 2 }
]
}
}
}
你會注意到我這裡多了一行 $schema
,這個是用來設定這個 JSON 的欄位格式。如果你是使用 VS Code 的話還會有自動補全和提示的功能。假如你怕自己編輯 JSON 檔案的格式或拼字有錯,可以多加這行,讓文字編輯器幫你做檢查,不然不加也可以,不會影響 QMK 的功能。
修改 keymap.c
keymaps
資料夾內可以放多種不同的鍵映射(Keymap),但是至少有有一個名為 default
的預設 Keymap。現在已經自動產生這個預設 keymap 了。打開 keymaps\default\keymap.c
。
這裡要修改的是 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {}
的內容,也就是 Keymap。Keymap 的結構與行列數量必須要與剛剛在 keyboard.json
中設定的 layout
中的 matrix
對應。
這裡要手動修改的話也是有一點麻煩,所以一樣推薦使用 Keyboard Firmware Builder,將 上一篇文章 最後的 Raw data 複製並貼到裡面。到最後一個標籤頁「Compile」按下「Download .zip」按鈕來儲存它產生的 QMK 韌體原始檔(舊版)。

將下載的 .zip
檔解壓縮,打開其中的 qmk_firmware\keyboards\kb\keymaps\default\keymap.c
。你會看到和我們所需要的 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {}
的內容,可以把複製到我們的鍵盤的 keymap.c
中。
不過它的每一個層的名稱是 KEYMAP()
,而我們剛剛產生的名稱是 LAYOUT
,所以這邊也要一同改成 LAYOUT()
。
LAYOUT()
中的這些就代表了鍵盤各個鍵位的按鍵功能。像是 KC_P7
代表了 Numpad7(數字鍵盤的 7),而詳細的按鍵名稱請參考 QMK 的說明文件:Keycodes Overview。
你所需要做的就是把該按鍵的代號(如 KC_P7
)放在對的位置就好了,之後你按下這個位置的按鍵就會是輸出這個鍵值。QMK 鍵盤支援多層 Keymap 設定,而每一塊 [n] = LAYOUT()
代表的是一層,最上面的是第 0 層,往下是第 1、2…n 層。
修改完的 keymap.c
大概長這樣:
#include QMK_KEYBOARD_H
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// clang-format off
[0] = LAYOUT(
KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
KC_P7, KC_P8, KC_P9,
KC_P4, KC_P5, KC_P6, KC_PPLS,
KC_P1, KC_P2, KC_P3,
KC_P0, MO(1), KC_PENT
),
[1] = LAYOUT(
_______, _______, _______, _______,
KC_HOME, KC_UP, KC_PGUP,
KC_LEFT, _______, KC_RGHT, _______,
KC_END, KC_DOWN, KC_PGDN,
KC_INS, _______, KC_DEL
)};
// clang-format on
有些人可能會喜歡加上一些圖案:
[0] = LAYOUT(
// ┌────────┬─────────┬──────────┬─────────┐
KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
// ├────────┼─────────┼──────────┼─────────┤
KC_P7, KC_P8, KC_P9,
// ├────────┼─────────┼──────────┤ │
KC_P4, KC_P5, KC_P6, KC_PPLS,
// ├────────┼─────────┼──────────┼─────────┤
KC_P1, KC_P2, KC_P3,
// ├────────┴─────────┼──────────┤ │
KC_P0, MO(1), KC_PENT
// └──────────────────┴──────────┴─────────┘
),
clang-format off
與clang-format on
是讓 VS Code 的 Clang-format 格式化工具不用美化該區域的內容,和功能無關可以不加。如果你稍微懂一點 C 語言的話,
LAYOUT()
就是是#define
巨集 Macro。
修改 rules.mk
Pro Micro 一般會分 16MHz/5V 和 8MHz/3.3V 這兩種版本,若你使用的是後者才需要執行這個修改 rules.mk
的步驟。
原始建立的檔案中沒有這個檔案,我們自行新增即可,放在和 keyboard.json
同一個層級。
請在 rules.mk
中加入:
# Processor frequency
F_CPU = 8000000
這部分的說明請參考:AVR MCU Options
請注意
rules.mk
中的各行結尾不能有空白,否則可能會導致奇怪的編譯錯誤,例如:Compiling: .build/obj_mytestkb/src/default_keyboard.c avr-gcc.exe: error: UL: No such file or directory
。
結語
到此為止,QMK 韌體原始檔的基本編輯就完成了,接下來就要準備進行編譯。
這一篇的內容可能比較複雜,且 QMK 也一直再更新,如果有我寫得不夠清楚或是有誤的地方,歡迎提出。
相關網站及參考資料
- 本 QMK 教學系列文列表
- Keyboard Firmware Builder
- Qwiic Pro Micro USB-C (ATmega32U4) Hookup Guide - SparkFun Learn
- QMK相關
- 撰寫本文時的工具版本
- QMK MSYS:
1.10.0
- QMK CLI:
1.1.6
- QMK MSYS:
留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)