初級(jí)QMK編譯入門教程

如果只是做常規(guī)鍵盤的話,用我之前文章里提到的QMK固件制作方法就足夠了。
但是人的欲望總是無盡的,當(dāng)看到那些客制化鍵盤上的OLED屏、旋鈕、分體鍵盤等等的時(shí)候,我的內(nèi)心又有一個(gè)聲音對(duì)我說:我全都要……

于是這個(gè)問題就變得復(fù)雜了……之前的編輯方法顯然不足以滿足這些需求了。于是就要對(duì)QMK固件進(jìn)行代碼級(jí)的編輯??瓷先ズ莒趴嵊袥]有????!
如果您并沒有QMK固件的制作經(jīng)驗(yàn),強(qiáng)烈建議先去看下我之前的那篇《改裝路透社小鍵盤,超詳細(xì)圖文講解QMK刷機(jī)教程》,網(wǎng)址:https://www.zfrontier.com/post/detail/18546
如果能照著做一遍就更好了,因?yàn)檫@篇文章里涉及的很多問題,其實(shí)就是將一些之前可視化的編程還原回代碼化了。
下手之前還是先到處搜索相關(guān)的教程帖子,發(fā)現(xiàn)國內(nèi)關(guān)于QMK固件編輯的教程少的可憐,加之祖?zhèn)鞯挠⒄Z渣渣,只能在網(wǎng)頁翻譯插件的幫助下,強(qiáng)行硬啃QMK主頁的官方教程了。其實(shí)現(xiàn)在想想還是挺有收獲的,有些問題當(dāng)時(shí)可能不太理解,但是大概看一眼,沒事念念不忘一下,沒準(zhǔn)什么時(shí)候就必有回響了……
QMK官方說明網(wǎng)址:https://docs.qmk.fm/#/
??
言歸正傳,把我經(jīng)過各種路子學(xué)到的一點(diǎn)鳳毛麟角的固件編輯知識(shí)分享給大家。其實(shí)也談不上教程,因?yàn)槲冶旧硪彩沁吤鬟厡懙?,如有不?guī)范或者疏漏,還往大神輕拍指正。
文中涉及的軟件:
ATOM:代碼編輯器??梢匀tom主頁免費(fèi)下載使用,地址:https://atom.io/
MSYS2:把代碼文件整合編譯成HEX格式的固件文件。也是免費(fèi)的,官網(wǎng)地址:https://www.msys2.org/
首先,去到QMK的GAYHUB(GAYHUB不是筆誤,你懂的。)主頁:https://github.com/qmk/qmk_firmware
點(diǎn)擊頁面右偏上角的綠色按鈕,在彈出的菜單中選擇Download ZIP。

得到qmk_firmware-master.zip,解壓縮成文件夾,然后把文件夾名字改為QMK,其實(shí)不改也行,主要是為了后面方便記憶,同時(shí)也可以少敲點(diǎn)字……然后把QMK文件夾放到C盤根目錄,原因同上……懶癌晚期就這樣……

下一步是要找到一個(gè)合適自己的鍵盤源文件,QMK自帶的鍵盤固件源文件都在keyboards文件夾中。對(duì)于小白來說,如果在keyboards里面能找到適合自己的鍵盤當(dāng)然是很幸運(yùn)的。
如何確定這些各種各樣的名稱的鍵盤,哪一個(gè)是自己想要的哪?對(duì)于我這種英文不好的人來說,我的辦法是看找鍵字,比如首先肯定知道自己想要什么配列的鍵盤,比如60%,那就搜索60,一般在給鍵盤命名的時(shí)候都會(huì)體現(xiàn)出按鍵數(shù)量或者比例。

如果很不幸,示例文件中沒有合適的布局,也可以通過去各種網(wǎng)站論壇上尋找接近的鍵盤,然后進(jìn)行個(gè)性化的修改。當(dāng)然,前提是你看上的這款鍵盤的作者大發(fā)慈悲的分享了他的源文件……
通過尋找QMK自帶的鍵盤示例,并沒有發(fā)現(xiàn)滿足我需求的鍵盤。所以只能通過尋找相近的案例文件,再進(jìn)行修改了,畢竟我是小白……讓我獨(dú)自寫一個(gè)完整的鍵盤固件,我還是有點(diǎn)力不從心的……
不過不管有沒有在QMK文件夾中找到自己滿意的鍵盤文件,都不要?jiǎng)h除它!后面還有用!
很幸運(yùn)的是,最近在thingiverse上,有一位ID為soapsrx的大神,分享了一款小鍵盤,有6個(gè)按鍵,一塊OLED 和一個(gè)旋鈕,這與我之前的需求很接近了。功能方面,我只需要在他的基礎(chǔ)上增加一些按鍵和rgb燈光就好了。外觀的話,借著3D打印機(jī)的淫威,基本都不是問題。
打開https://www.thingiverse.com/thing:4134988
點(diǎn)擊右上角藍(lán)色按鈕。下載得到+Mechanical+Keyboard+-+SiCK-68+Encoder+Oled+Display.zip。解壓縮。

在解壓后的文件夾內(nèi),打開files->mak01->mak01文件夾。
然后我們看到的這些文件,就是制作QMK固件的最基本的文件構(gòu)成了。

QMK固件構(gòu)成文件簡單介紹:
keymaps->default->keymap.c 負(fù)責(zé)鍵位、鍵層設(shè)置,旋鈕功能設(shè)置,oeld功能設(shè)置等等
rules.mk 相當(dāng)于總開關(guān),使用什么開發(fā)板,鍵盤開啟和關(guān)閉什么功能,都要在這個(gè)文件中設(shè)置。
config,h 可以設(shè)置鍵盤的設(shè)備名稱等相關(guān)信息,還有針腳設(shè)置,RGB燈光設(shè)置等等。
mak01,h 這個(gè)文件中的鍵值配列要與keymap.c中的對(duì)應(yīng)。一般情況下,只要不改變配列,只是修改按鍵定義的話,就不用動(dòng)這個(gè)文件了。
mak01,c 這個(gè)我也不知道干什么的,但是要保證里面的內(nèi)容指向同名的.h文件。一般不修改這個(gè)文件。
readme,md 說明文件,不用理會(huì)。
除了這些最基本的文件,對(duì)于一些功能復(fù)雜的鍵盤來說,他的文件會(huì)多出很多其他文件,但是萬變不離其中,對(duì)于我這種初學(xué)者來說,多看看其他鍵盤的示例文件也可以學(xué)到很多東西。
這些文件分工不同,相互關(guān)聯(lián),所以很多修改往往要涉及到幾個(gè)文件的編輯。
比如增加旋鈕(編碼器)功能:
首先要在rules.mk中開啟旋鈕功能
然后在config,h中設(shè)置旋鈕連接的針腳以及靈敏度等
最后在keymap.c設(shè)置旋鈕的功能
??
打開rules.mk。
用atom文件打開以后,就是下圖這種畫風(fēng)的,炸一看全是字,感覺比較高深,其實(shí)主要原因我覺得是因?yàn)槿怯⑽摹绻⒄Z比較好,或者耐下心來翻譯一下的話,也就沒那么難了。其實(shí)這些文件用WIN自帶的記事本也可以編輯,用編輯軟件的好處就是,軟件會(huì)根據(jù)代碼的格式,自動(dòng)將功能相同的內(nèi)容統(tǒng)一成一個(gè)顏色,同時(shí)還會(huì)在每行的前面加一個(gè)行數(shù),方便查找。
如下圖,紅字是代碼的功能名稱,白字是可以修改的選項(xiàng),灰字是注釋文字。
注釋文字的頭尾都會(huì)有特定的符號(hào),用這些符號(hào)開頭或者夾在這些符號(hào)中的文字,就會(huì)被識(shí)別為注釋文字。注釋文字的作用是方便記憶,并且支持中文。

可以看到,這個(gè)文件的編輯者有一個(gè)很好的習(xí)慣,就是將開啟和關(guān)閉的功能,分為兩組。其實(shí)QMK對(duì)這些代碼的行順序是沒有強(qiáng)制要求的,而且默認(rèn)的代碼的順序也不是這樣嚴(yán)格區(qū)分的,按照何種方式歸類完全根據(jù)個(gè)人喜好。
第2行是設(shè)置開發(fā)板芯片型號(hào)的,我這里使用的是Teensy2.0開發(fā)板,所以芯片型號(hào)改成ATmega32U4。
第12行,根據(jù)開發(fā)板的型號(hào),修改啟動(dòng)類型,Teensy2.0對(duì)應(yīng)的是halfkay。
第34行是rgb燈光開關(guān),復(fù)制到上面,改成yes。
保存,關(guān)閉。

??
如果有命令不知道是干什么用的,可以去QMK官網(wǎng)搜索。
網(wǎng)址:https://docs.qmk.fm/#/
打開網(wǎng)頁以后,點(diǎn)擊左上角的Search,然后把搞不懂的代碼粘貼上去,搜索一下,一般就能找到說明了。

比如搜索:COMMAND_ENABLE,然后就會(huì)找到跟這條代碼相關(guān)的所有內(nèi)容,英文不好的話,用瀏覽器插件翻譯一下,大概就能知道這個(gè)代碼的作用了。

??
就像前面說的,rules.mk文件只相當(dāng)于一個(gè)總開關(guān),這幾個(gè)功能雖然開啟了,但是具體如何使用,就要在config.h中進(jìn)行設(shè)置了。PS一句,rules.mk中并不是將QMK所有的功能都列在其中了,沒寫入進(jìn)去的就默認(rèn)為關(guān)閉了。不過,為什么不把代碼里面標(biāo)記為NO的都刪除了哪?我也不知道……盡量還是不要大改動(dòng)了,以免出現(xiàn)超出自己解決能力的錯(cuò)誤……
打開config.h。
還是一行行的代碼,還是要靜下心一條條的看……
26、27、28三行代碼是修改設(shè)備品牌、名稱和描述的,無關(guān)痛癢,只是連接電腦后顯示的設(shè)備名。
第31和32行是設(shè)置鍵盤按鍵的行列數(shù),這個(gè)20鍵的小鍵盤是5行4列。
36和37行是設(shè)置行和列對(duì)應(yīng)的開發(fā)板針腳,第50行是設(shè)置二極管的方向是行到列還是列到行。這些跟我們之前在kbfirmware.com上做的其實(shí)是一個(gè)原理,只不過KBF上將這一過程可視化了。

與rules.mk文件中的工整相比,config.h文件的編寫明顯偷懶了……原作一個(gè)2*3的6鍵配列,文件中竟然是5*19的配列……反正我都要改成5*4,順手就改了吧。同時(shí)對(duì)應(yīng)的針腳數(shù)量也要與行列數(shù)對(duì)應(yīng)。

插播一下,由于改變了原本的配列,所以要對(duì)mak01.h進(jìn)行編輯,將里面的鍵值也改成5*4的,也就是每行保留4個(gè)鍵值,一共5行。兩個(gè)鍵層都要這樣。當(dāng)然,如果只是修改按鍵功能,不改變配列的話,就可以省略這一步了。

回到config.h文件接著往下看,下圖中:
第47行,修改延遲的,由于按鍵開關(guān)的物理特性,在按下去的過程中,都會(huì)產(chǎn)生一些很細(xì)微的顫抖,如果不增加一個(gè)容錯(cuò)時(shí)間,很可能感覺是按了一下,但是在極端的時(shí)間內(nèi),按鍵已經(jīng)經(jīng)歷了多次開關(guān)的過程,這樣就容易造成誤觸。但是這個(gè)容錯(cuò)時(shí)間又不能太長,太長的話,按鍵就會(huì)延遲過長了,影響輸入。QMK的默認(rèn)值是5,也就是0.005秒,一般情況下這個(gè)數(shù)值不用修改。
第50行和第52行不用動(dòng)。
后面的幾行,在圖中注釋了。

在keymaps->default文件夾中,還有一個(gè)config.h文件,里面是旋鈕編碼器的針腳設(shè)置,一般來說,這個(gè)代碼寫在前面那個(gè)config.h就可以。出于一個(gè)新手的小心謹(jǐn)慎,還是不要把這兩個(gè)文件合并到一起吧……

需要注意的是,在設(shè)置針腳的時(shí)候,不要占用D1和D2針腳,因?yàn)檫@兩個(gè)針腳除了可以當(dāng)做普通針腳以外,還是開發(fā)板的通訊針腳,要留給OLED 屏幕使用。
打開keymaps->default文件夾中的keymap.c文件,如下圖。
與修改config.h時(shí)候看到的行列數(shù)一樣,keymap.c文件中設(shè)置的果然5*19的配列……并且有兩個(gè)鍵層(LAYOUT),根據(jù)需要,按照QMK的鍵值表,進(jìn)行修改。但是在修改的時(shí)候一定要注意保持原有代碼結(jié)構(gòu),只修改橙色的鍵值即可,一個(gè)標(biāo)點(diǎn)符號(hào)都不要?jiǎng)?。而且要特別留神那些標(biāo)點(diǎn)符號(hào)!比如每行鍵值的最后都有一個(gè)逗號(hào),但是最后一行鍵值的結(jié)尾卻沒有……如果編輯的時(shí)候不小心也打上逗號(hào),就會(huì)編譯失敗了……就是這么的嚴(yán)謹(jǐn)……

QMK鍵值地址:https://docs.qmk.fm/#/keycodes_basic
根據(jù)我自己的用途調(diào)整好的按鍵設(shè)置如下圖,在小鍵盤上增加了退格鍵,是為了方便使用計(jì)算器的時(shí)候刪除數(shù)字。右上角的按鍵是播放暫停鍵,對(duì)應(yīng)到編碼器的按鍵功能上,這樣按下編碼器就可以控制播放器了。左下角TO的鍵值是切換鍵層用的,兩個(gè)鍵層要可以相互切換才行。

再往下的一段代碼是關(guān)于OLED的,其中綠色的代碼為最終將要顯示在OLED上的文字,不支持漢字……QMK默認(rèn)的OLED為128*32分辨率的,這段設(shè)置中,將OLED分為四行顯示:
第一行為Layer:,后面的文字根據(jù)激活的鍵層顯示,BASE鍵層是顯示Default,F(xiàn)UNCTION鍵層時(shí)顯示PhonoShop。
第二行是“-------”分割線。
第三行是Stats:
第四行為跟鍵盤LED的功能相同,顯示NUM和CAP時(shí)表示激活小鍵盤和大寫,反之同理。
??QMK默認(rèn)開啟的OLED屏幕分辨率為128*32,也可以支持128*64的OLED,需要額外加一條代碼聲明一下。
??
最后一段代碼是旋鈕,也就是編碼器功能的設(shè)置,本著挑看得懂的改的原則,將正轉(zhuǎn)和反轉(zhuǎn)的鍵值設(shè)定為音量大小調(diào)節(jié)。
官方提供的編碼器范例代碼是對(duì)應(yīng)兩個(gè)編碼器,自己在編輯的時(shí)候去掉一個(gè)編碼器的代碼就行了。刪除代碼的時(shí)候要注意大括號(hào)的對(duì)應(yīng)關(guān)系,保證大括號(hào)都是成對(duì)出現(xiàn)的。
至此,按鍵不多,卻包含了比較流行的元素的鍵盤固件源文件就基本寫好了,下一步就要把這些文件編譯成固件文件了。
??
還記得文章一開始提到的QMK文件夾么?將剛才編譯的那些文件所在的MAK01文件夾拷貝到C->QMK->keyboards文件夾中。
MSYS2安裝好以后還要配置下開發(fā)環(huán)境,具體教程可以參閱:https://post.smzdm.com/p/az50xgpo/
特別感謝一下這篇文章的作者qianseyue,網(wǎng)上比較容易找到的幾篇關(guān)于QMK的文章都是qianseyue老師寫的。
配置好以后,打開MSYS2,輸入cd空格/c/qmk回車,然后再輸入make空格mak01:default回車,沒有意外的話,就會(huì)像下圖這樣,一路OK。
??當(dāng)然,一路OK的情況在編譯當(dāng)中并不是一下子就能得到的,正常情況下都會(huì)有點(diǎn)錯(cuò)誤,這個(gè)時(shí)候就要冷靜分析原因了。好在QMK很貼心的提示了編譯失敗的原因。
比如下圖這種錯(cuò)誤,我們可以看到熟悉的文件名keymap.c,后面的C:39:5,是錯(cuò)誤出現(xiàn)在代碼的第39行的第5個(gè)字。再往下提示出錯(cuò)誤的具體位置,是括號(hào)和逗號(hào)出問題了。
于是回到編輯器,查看keymap.c的代碼,找到第39行,發(fā)現(xiàn)括號(hào)和逗號(hào)并沒有問題,但是查看附近的代碼,通過上下兩個(gè)鍵層的對(duì)比,可以看出,第一鍵層的最后一個(gè)按鍵后面比第二鍵層多了一個(gè)逗號(hào),這就是導(dǎo)致報(bào)錯(cuò)的原因,刪除這個(gè)逗號(hào),保存文件,再次編譯,問題就解決了。
??
最后,然后去到QMK文件夾下的,build文件里,找到一個(gè)hex格式的文件,就是我們做好的固件了。
??
將固件文件刷入開發(fā)板,TEENSY 2.0的刷固件方法可以看我另一篇文章《3D打印機(jī)械鍵盤制作-附超詳細(xì)Teensy 2.0主控制作教程》地址:https://www.zfrontier.com/post/detail/18651
刷好固件以后,系統(tǒng)就會(huì)識(shí)別出鍵盤了,雖然只是一個(gè)沒有連接任何零件的開發(fā)板。
??
看了下文章長度,好像有點(diǎn)長……于是就在主控刷好固件這里告一段落,下一篇著重說鍵盤硬件部分的搭建。
最最后說一句,這里說到的某些代碼可能會(huì)在后面實(shí)際測試以后發(fā)現(xiàn)錯(cuò)誤,如果有這種情況我會(huì)在后面的文章中指出更正。

??QMK默認(rèn)開啟的OLED屏幕分辨率為128*32,也可以支持128*64的OLED,需要額外加一條代碼聲明一下。
??
最后一段代碼是旋鈕,也就是編碼器功能的設(shè)置,本著挑看得懂的改的原則,將正轉(zhuǎn)和反轉(zhuǎn)的鍵值設(shè)定為音量大小調(diào)節(jié)。

官方提供的編碼器范例代碼是對(duì)應(yīng)兩個(gè)編碼器,自己在編輯的時(shí)候去掉一個(gè)編碼器的代碼就行了。刪除代碼的時(shí)候要注意大括號(hào)的對(duì)應(yīng)關(guān)系,保證大括號(hào)都是成對(duì)出現(xiàn)的。

至此,按鍵不多,卻包含了比較流行的元素的鍵盤固件源文件就基本寫好了,下一步就要把這些文件編譯成固件文件了。
??
還記得文章一開始提到的QMK文件夾么?將剛才編譯的那些文件所在的MAK01文件夾拷貝到C->QMK->keyboards文件夾中。

MSYS2安裝好以后還要配置下開發(fā)環(huán)境,具體教程可以參閱:https://post.smzdm.com/p/az50xgpo/
特別感謝一下這篇文章的作者qianseyue,網(wǎng)上比較容易找到的幾篇關(guān)于QMK的文章都是qianseyue老師寫的。
配置好以后,打開MSYS2,輸入cd空格/c/qmk回車,然后再輸入make空格mak01:default回車,沒有意外的話,就會(huì)像下圖這樣,一路OK。

??當(dāng)然,一路OK的情況在編譯當(dāng)中并不是一下子就能得到的,正常情況下都會(huì)有點(diǎn)錯(cuò)誤,這個(gè)時(shí)候就要冷靜分析原因了。好在QMK很貼心的提示了編譯失敗的原因。
比如下圖這種錯(cuò)誤,我們可以看到熟悉的文件名keymap.c,后面的C:39:5,是錯(cuò)誤出現(xiàn)在代碼的第39行的第5個(gè)字。再往下提示出錯(cuò)誤的具體位置,是括號(hào)和逗號(hào)出問題了。

于是回到編輯器,查看keymap.c的代碼,找到第39行,發(fā)現(xiàn)括號(hào)和逗號(hào)并沒有問題,但是查看附近的代碼,通過上下兩個(gè)鍵層的對(duì)比,可以看出,第一鍵層的最后一個(gè)按鍵后面比第二鍵層多了一個(gè)逗號(hào),這就是導(dǎo)致報(bào)錯(cuò)的原因,刪除這個(gè)逗號(hào),保存文件,再次編譯,問題就解決了。

??
最后,然后去到QMK文件夾下的,build文件里,找到一個(gè)hex格式的文件,就是我們做好的固件了。

??
將固件文件刷入開發(fā)板,TEENSY 2.0的刷固件方法可以看我另一篇文章《3D打印機(jī)械鍵盤制作-附超詳細(xì)Teensy 2.0主控制作教程》地址:https://www.zfrontier.com/post/detail/18651
刷好固件以后,系統(tǒng)就會(huì)識(shí)別出鍵盤了,雖然只是一個(gè)沒有連接任何零件的開發(fā)板。

??
看了下文章長度,好像有點(diǎn)長……于是就在主控刷好固件這里告一段落,下一篇著重說鍵盤硬件部分的搭建。
最最后說一句,這里說到的某些代碼可能會(huì)在后面實(shí)際測試以后發(fā)現(xiàn)錯(cuò)誤,如果有這種情況我會(huì)在后面的文章中指出更正。