客制化鍵盤,這是一個巨大的坑,形形色色的軸體、外殼、PCB、數據線、鍵帽、燈效、音效甚至掌託,對於熱愛DIY的玩家們來說,確實很吸引人,但再看看價格,只能打擾了。作為一隻程序猿,想要玩客制化鍵盤又玩不起,就只能對著鍵盤的固件深入研究一番了。在我的前一篇文章中,一步步搭建起了QMK固件在Windows系統中的編譯環境,接下來就著手打造自己的鍵盤固件吧。
建立自己的KEYBOARD 和KEYMAP
在終端中使用命令./util/new_keyboard.sh,輸入自己為鍵盤取的名稱(mini01)、使用的晶片(默認AVR)、自己的github用戶名,生成自己的KEYBOARD文件夾和配置文件。
再輸入./util/new_keymap.sh KEYBOARD NAME,這裡的KEYBOARD替換為上一步取的鍵盤名稱mini01,NAME是自己的github用戶名,生成自己的KEYMAP示例文件。兩條命令中自己的名字主要是為了生成一些文檔中的名字部分,讓看到鍵盤文檔的廣大網友認識你,在意的話就好好想個好名字,不關心的話隨意取都可以。
此時可看到在固件目錄./keyboards中生成了一個以剛才輸入名稱(mini01)命名的文件夾,裡面有rules.mk、config.h等示例配置文件,文件夾./keyboards/mini01/keymaps中為示例的KEYMAP相關文件。
修改KEYBOARD 和KEYMAP
這裡以5個按鍵的小鍵盤為例,主控使用Arduino leonardo,為了快速入門,儘量只對固件做最少的修改,先讓這個鍵盤能用起來。
/mini01/rules.mk
rules.mk是用來控制編譯選項的文件,在該文件中可打開或關閉一些功能。文件中#號後是注釋,為我們解釋了相關編譯選項的意義。
MCU是鍵盤所使用的主控型號,目前使用的Arduino leonardo,其主控是Atmega32u4,所以MCU = atmega32u4不用修改,如果使用了其他主控晶片,修改為相應的名稱就好,比如MCU = STM32F303。
如果使用ATmel晶片作為主控,需要定義主控晶片使用的bootloader,示例文件中已經列出了可能的bootloader種類,通常使用默認的BOOTLOADER = atmel-dfu即可。如果使用STM32主控,由於STM32主控晶片的bootloader是固化在晶片內部的,僅與前面定義的MCU型號相關,因此注釋掉此行即可。其他選項暫時不作修改。
/mini01/config.h
矩陣鍵盤電路均是將按鍵開關分為多行多列,這裡的行列不是從表面上看到的鍵帽排列的行列,而是PCB上各個按鍵組成的矩陣鍵盤的排列。
MATRIXROWS定義為矩陣鍵盤的行數,此鍵盤為2;MATRIXCOLS定義為矩陣鍵盤的列數,此鍵盤為3。行列之間通過按鍵開關和防止按鍵衝突的二極體連接,這裡需要定義二極體的從正極到負極的方向。大多數二極體都是有色環的一方為負極,從上圖看,二極體有色環的一方連接到了矩陣鍵盤的行上,因此方向為列到行,#define DIODE_DIRECTION COL2ROW。
每一行和列分別連接到主控晶片的某一個GPIO(LEONARDO PINOUT中的Port Pin),在config.h文件中主要就是定義這些GPIO的連接情況。MATRIX_ROW_PINS 對應矩陣鍵盤PCB上每一行連接的GPIO,#define MATRIX_ROW_PINS { D1, D0 },MATRIX_COL_PINS 對應矩陣鍵盤PCB上每一列連接的GPIO,#define MATRIX_COL_PINS { D4, C6, D7 }。
/mini01/mini01.h
此文件內定義的宏LAYOUT是一種映射關係,將從正面看鍵盤的鍵位布局映射為從透視到鍵盤背面的矩陣鍵盤電路連接情況。定義這個宏是為了方便後面的按鍵功能定義,LAYOUT後緊跟的()括號內,knm的n表示按鍵在第幾行,m表示按鍵在第幾列,排列與正面看的鍵位布局一致,方便定義功能時對應到相應鍵位,而不用關心PCB上的電路連接情況。{}括號內,是二維數組形式,必須滿足前面定義的行列數,每一行為矩陣鍵盤電路上連接在一起的一行,如果某行某列無按鍵,必須使用KC_NO填充。
/mini01/datou/keymap.c
在keymap.c中就可以按照按鍵的位置來定義功能,對於標準的104鍵的鍵盤,普通的功能均可以使用下圖的定義。
這裡先把鍵盤定義為兩層,第0層按鍵實現上下左右,第1層按鍵實現數字1234。
生成的默認文件內也是定義的兩層,我們把每一層的名字修改一下,方便識別,當然也可以不修改。
keymaps[][MATRIX_ROWS][MATRIX_ROWS][MATRIX_COLS]就是定義鍵盤功能的數組了,每一層按鍵功能使用了一個的LAYOUT來定義功能。MO(NUMBER)表示按住該鍵時,鍵盤功能映射為NUMBER這一層,實現數字按鍵1234的功能。_______表示與n-1層的功能相同(n為按鍵所在的層),比如下圖第1層的_______的功能就是第0層對應位置按鍵的功能,也就是MO(NUMBER)。
編譯固件
至此,這個極其簡單的5個按鍵的鍵盤固件就修改完了,最後使用命令qmk compile -kb mini01 -km datou編譯生成固件,一切順利。