summaryrefslogtreecommitdiffstats
path: root/docs/zh-cn
diff options
context:
space:
mode:
Diffstat (limited to 'docs/zh-cn')
-rw-r--r--docs/zh-cn/_summary.md66
-rw-r--r--docs/zh-cn/contributing.md205
-rw-r--r--docs/zh-cn/custom_quantum_functions.md490
-rw-r--r--docs/zh-cn/faq.md6
-rw-r--r--docs/zh-cn/faq_build.md150
-rw-r--r--docs/zh-cn/faq_debug.md233
-rw-r--r--docs/zh-cn/faq_general.md19
-rw-r--r--docs/zh-cn/faq_keymap.md212
-rw-r--r--docs/zh-cn/getting_started_getting_help.md15
-rw-r--r--docs/zh-cn/getting_started_github.md59
-rw-r--r--docs/zh-cn/newbs.md23
-rw-r--r--docs/zh-cn/reference_glossary.md170
12 files changed, 1615 insertions, 33 deletions
diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md
index df25a3ccd1..b0d9f1c068 100644
--- a/docs/zh-cn/_summary.md
+++ b/docs/zh-cn/_summary.md
@@ -7,27 +7,27 @@
* [学习资源](newbs_learn_more_resources.md)
* [QMK基础](README.md)
- * [QMK 简介](getting_started_introduction.md)
- * [贡献 QMK](contributing.md)
+ * [QMK简介](getting_started_introduction.md)
+ * [向QMK贡献](contributing.md)
* [如何使用Github](getting_started_github.md)
* [获得帮助](getting_started_getting_help.md)
* [问题解答](faq.md)
* [一般问题](faq_general.md)
- * [构建/编译QMK](faq_build.md)
- * [调试/故障排除 QMK](faq_debug.md)
- * [键盘布局](faq_keymap.md)
+ * [构建/编译](faq_build.md)
+ * [调试/故障排除](faq_debug.md)
+ * [键盘映射](faq_keymap.md)
* 详细指南
* [安装构建工具](getting_started_build_tools.md)
- * [流浪者指南](getting_started_vagrant.md)
+ * [vagrant指南](getting_started_vagrant.md)
* [构建/编译指令](getting_started_make_guide.md)
* [刷新固件](flashing.md)
* [定制功能](custom_quantum_functions.md)
- * [布局概述](keymap.md)
+ * [映射概述](keymap.md)
* [硬件](hardware.md)
- * [AVR 处理器](hardware_avr.md)
+ * [AVR处理器](hardware_avr.md)
* [驱动](hardware_drivers.md)
* 参考
@@ -35,8 +35,8 @@
* [配置选项](config_options.md)
* [键码](keycodes.md)
* [记录最佳实践](documentation_best_practices.md)
- * [文档指南](documentation_templates.md)
- * [词汇表](reference_glossary.md)
+ * [文档模板](documentation_templates.md)
+ * [术语表](reference_glossary.md)
* [单元测试](unit_testing.md)
* [有用的功能](ref_functions.md)
* [配置器支持](reference_configurator_support.md)
@@ -44,35 +44,35 @@
* [特性](features.md)
* [基本键码](keycodes_basic.md)
- * [US ANSI 控制键](keycodes_us_ansi_shifted.md)
+ * [US ANSI控制码](keycodes_us_ansi_shifted.md)
* [量子键码](quantum_keycodes.md)
* [高级键码](feature_advanced_keycodes.md)
* [音频](feature_audio.md)
- * [自动控制](feature_auto_shift.md)
+ * [自动shift](feature_auto_shift.md)
* [背光](feature_backlight.md)
* [蓝牙](feature_bluetooth.md)
- * [Bootmagic](feature_bootmagic.md)
+ * [热改键](feature_bootmagic.md)
* [组合](feature_combo)
* [命令](feature_command.md)
* [动态宏指令](feature_dynamic_macros.md)
* [编码器](feature_encoders.md)
- * [Grave Escape](feature_grave_esc.md)
- * [键锁](feature_key_lock.md)
- * [层](feature_layouts.md)
- * [引导键](feature_leader_key.md)
- * [LED 阵列](feature_led_matrix.md)
+ * [重音号Esc复合键](feature_grave_esc.md)
+ * [自锁键](feature_key_lock.md)
+ * [布局](feature_layouts.md)
+ * [前导键](feature_leader_key.md)
+ * [LED阵列](feature_led_matrix.md)
* [宏指令](feature_macros.md)
* [鼠标键](feature_mouse_keys.md)
* [一键功能](feature_advanced_keycodes.md#one-shot-keys)
* [指针设备](feature_pointing_device.md)
- * [PS/2 鼠标](feature_ps2_mouse.md)
- * [RGB 光](feature_rgblight.md)
- * [RGB 矩阵](feature_rgb_matrix.md)
+ * [PS/2鼠标](feature_ps2_mouse.md)
+ * [RGB灯光](feature_rgblight.md)
+ * [RGB矩阵](feature_rgb_matrix.md)
* [空格候补换挡](feature_space_cadet_shift.md)
* [空格候补换挡回车](feature_space_cadet_shift_enter.md)
* [速录机](feature_stenography.md)
* [换手](feature_swap_hands.md)
- * [踢踏舞](feature_tap_dance.md)
+ * [多击键](feature_tap_dance.md)
* [终端](feature_terminal.md)
* [热敏打印机](feature_thermal_printer.md)
* [Unicode](feature_unicode.md)
@@ -80,16 +80,16 @@
* [速度键](feature_velocikey.md)
* 针对制造者和定制者
- * [飞线指南](hand_wire.md)
- * [ISP 刷新指南](isp_flashing_guide.md)
- * [ARM 调试指南](arm_debugging.md)
- * [I2C 驱动](i2c_driver.md)
- * [GPIO 控制器](internals_gpio_control.md)
- * [Proton C 转换](proton_c_conversion.md)
+ * [手工连线指南](hand_wire.md)
+ * [ISP刷新指南](isp_flashing_guide.md)
+ * [ARM调试指南](arm_debugging.md)
+ * [I2C驱动](i2c_driver.md)
+ * [GPIO控制器](internals_gpio_control.md)
+ * [Proton C转换](proton_c_conversion.md)
* 深入了解
* [键盘如何工作](how_keyboards_work.md)
- * [理解 QMK](understanding_qmk.md)
+ * [理解QMK](understanding_qmk.md)
* 其他话题
* [使用Eclipse开发QMK](other_eclipse.md)
@@ -99,8 +99,8 @@
* QMK 内构 (正在编写)
* [定义](internals_defines.md)
* [输入回调寄存器](internals_input_callback_reg.md)
- * [Midi 设备](internals_midi_device.md)
- * [Midi 设备设置过程](internals_midi_device_setup_process.md)
- * [Midi 工具库](internals_midi_util.md)
+ * [Midi设备](internals_midi_device.md)
+ * [Midi设备设置过程](internals_midi_device_setup_process.md)
+ * [Midi工具库](internals_midi_util.md)
* [发送函数](internals_send_functions.md)
- * [Sysex 工具](internals_sysex_tools.md)
+ * [Sysex工具](internals_sysex_tools.md)
diff --git a/docs/zh-cn/contributing.md b/docs/zh-cn/contributing.md
new file mode 100644
index 0000000000..62b956b619
--- /dev/null
+++ b/docs/zh-cn/contributing.md
@@ -0,0 +1,205 @@
+# 如何做贡献
+
+👍🎉 首先感谢各位百忙之中抽空阅读本文档,并为我们无私奉献。给您点赞啦! 🎉👍
+
+第三方的帮助让Q酱成长了许多呢,Q酱也从你们那学到了不少新东西。Q酱希望每一个想帮助我的人都能很方便的做出有用的贡献。在这里我给摩拳擦掌的你们写了一点引导,让你们的代码在不对我做重大改动的情况下都能成功的被采纳哦。
+
+* [项目概况](#项目概况)
+* [代码规范](#代码规范)
+* [一般教程](#一般教程)
+* [行为守则对于我来说有何意义?](#行为守则对于我来说有何意义?)
+
+## 这文章巨长无比不想读啊! 我就想问个问题而已!
+
+您要是想问关于Q酱的问题的话可以在[OLKB Subreddit](https://reddit.com/r/olkb)或者是[Discord](https://discord.gg/Uq7gcHh)随意问。
+
+请记住:
+
+* 维护Q酱的小可爱有的时候可能会有点忙,不能及时回答您的问题,耐心等等,他们都是很nice的人呀。
+* 维护Q酱的人都是很无私的善良的人。无论是贡献代码还是回答问题,都是义务的。有时见到他们努力回答各种问题,解决各种BUG,Q酱也是很心疼的。
+* 您可以看看下面的教程,可以让您的问题浅显易懂,更容易回答:
+ * https://opensource.com/life/16/10/how-ask-technical-questions
+ * http://www.catb.org/esr/faqs/smart-questions.html
+
+# 项目概况
+
+Q酱很大一部分是用C语言组成的,不过有一小部分特性是C++的。怎么说呢,都是我的一部分,两个我都爱。Q酱一般是在键盘上的嵌入式处理器那里工作的,尤其与AVR([LUFA](http://www.fourwalledcubicle.com/LUFA.php))和ARM ([ChibiOS](http://www.chibios.com))两小哥哥搭配,干活不累,嘻嘻。如果您精通Arduino的话您会发现很多熟悉的概念,但也有点不爽,因为您以前的经验可能没法用来帮助Q酱。
+
+<!-- 需要修正: 这里放些学习C语言的资源。另外感谢修正的小可爱。谢谢您了。-->
+
+# Q酱,我在哪能帮助你嘞?
+
+您要是有问题的话可以 [提出一个issue](https://github.com/qmk/qmk_firmware/issues) 或 [在Discord上交流一下](https://discord.gg/Uq7gcHh).
+
+# Q酱,我如何帮助你?
+
+您以前是否没为开源贡献过代码,而又想知道帮助Q酱是怎么一回事? 稍安勿躁,咱给您总结一下!
+
+0. 先注册一个 [GitHub](https://github.com) 账户。
+1. 做好一个你要贡献的布局,那就要 [找一个你想解决的问题](https://github.com/qmk/qmk_firmware/issues),或者 [找一个你想添加的特性](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)。
+2. 把关联着问题的仓库分叉(fork)到你的仓库。这样你在`你的GitHub用户名/qmk_firmware`就有一个仓库备份啦。
+3. 使用 `git clone https://github.com/此处添GitHub用户名/此处添仓库名.git`这个命令把仓库同步到你的电脑中。
+4. 您要是想开发一个新特性的话可以先创建一个issue和Q酱的维护者讨论一下您要做什么。
+5. 使用`git checkout -b 此处写分支名字(别用汉字)`命令来创建一个分支(branch)用于开发。
+6. 对要解决的问题或要添加的特性进行适当的更改。
+7. 使用 `git add 把改变的文件的目录写这里` 可以添加改变的文件内容到git用于管理工程状态的索引(快照)里。
+8. 使用 `git commit -m "这里写修改的相关信息"` 来描述你做出了什么修改。
+9. 使用 `git push origin 此处写分支名字`来把你的更改同步到GitHub库里(反正不是打篮球那个库里)。
+10. 提交一个[QMK 固件的pull request](https://github.com/qmk/qmk_firmware/pull/new/master)。
+11. 给你的pull request拟一个标题,包括简短的描述和问题或错误代码。比如, 你可以起一个这样的"Added more log outputting to resolve #4352"(最好用英语,毕竟Q酱的中文也不是那么的溜,有可能会看不懂中文)。
+12. 在描述(description)里面写你做了哪些更改,你的代码里还存在什么问题, 或者你想问维护的小可爱们的问题。你的your pull request有点小问题无伤大雅(本来也没有完美的代码嘛), 维护的小可爱们会竭尽全力帮您改进的!
+13. 维护人员审查代码可能需要一些时间。
+14. 维护人员会通知您要更改什么地方,然后您就按照建议改一改。
+15. 预祝您合并成功!
+
+# 代码规范
+
+其实也没有什么特别严格的规范啦,但是俗话说的好:没有规矩,不成方圆。您可以看一下您的要改动的代码周围的画风,然后保持队形。如果你感觉周围都不知道是什么牛鬼蛇神的话就看看下面的建议:
+
+* 我们用肆(4)个空格来缩进(软件中也可以设置到Tab键)
+* 我们使用改良的1TBS(允许单行样式)
+ * 左大括号: 在开放性语句块那行的末尾
+ * 右大括号: 和开放性语句块第一个字母对齐
+ * Else If: 将右大括号放在行的开头,下一个左大括号放在同一行的结尾
+ * 可选大括号: 可选大括号是必选的
+ * 应该这样: if (condition) { return false; }
+ * 不应该这样: if (condition) return false;
+* 建议使用C语言风格的注释: `/* */`
+ * 把注释想象成一个描述特征的故事
+ * 充分使用注释来描述你为何这样修改
+ * 有些公认的东西就不要写到注释里面了
+ * 如果你不知道注释是否多余,看下面
+* 一般不要主动换行,主动换行的话每行不要超过76列
+* 要把 `#pragma once` 放到头文件的开始哦,抛弃老土的(`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`)吧
+* 下面两种预处理命令都可以用: `#ifdef DEFINED` 还有 `#if defined(DEFINED)`
+ * 以上那句对处女座不是很友好哈,处女座的朋友们就别纠结了,直接 `#if defined(DEFINED)` 。
+ * 还有就是选好一种风格就一直用,一直用一直爽,不要朝三暮四, 除非你要变化到多重条件的 `#if`。
+ * `#` 和 `if`要挨在一起哦,再让本空格在中间冒充电灯泡本空格会生气的。
+ * 以下是缩进规则:
+ * 首先考虑可读性,强迫症的朋友们总想要保持代码的高一致性,这样可不好。
+ * 保证文件已有风格不变。如果代码本来就是杂糅风格,那就见机行事,让你的修改更有意义些。
+ * 其实你也可以在缩进的时候看看周围其他代码,然后范水模山,预处理命令可以有自己的缩进风格。
+
+可以参照下面:
+
+```c
+/* foo 的 Enums*/
+enum foo_state {
+ FOO_BAR,
+ FOO_BAZ,
+};
+
+/* 有返回值的情况 */
+int foo(void) {
+ if (some_condition) {
+ return FOO_BAR;
+ } else {
+ return -1;
+ }
+}
+```
+
+# Clang-format的自动格式化
+[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) 是LLVM的一部分,可以帮你自动格式化代码。我们给你准备好了一个适用于以上规范的配置文件,会帮你调整缩进和换行,你只需要写好括号就好。有了它,你再也不用担心调整代码格式太耗时,没有时间陪伴自己(虚构)的另一半了。
+
+使用[LLVM 完整安装](http://llvm.org/builds/)可以在Windows上安装clang-format, Ubuntu用户要用`sudo apt install clang-format`。
+
+命令行的朋友们, 加上 `-style=file`选项就会自动在QMK的根目录寻找.clang-format配置文件了。
+
+VSCode用户, 标准的 C/C++ 插件就支持clang-format, 或者可以用[独立扩展](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat)也行。
+
+有些东西(比如LAYOUT宏) 会被clang-format打乱,所以那些文件就别用clang-format了,这里就教您一个小窍门,在`// clang-format off` 和 `//clang-format on`之间装上会被搞乱的代码就好了。
+
+# 一般教程
+
+你可以给Q酱的不同部分添砖加瓦,但也要用不同的方法严谨检查。不论你修改哪里最好还是看看下边。
+
+* 将PR(pull request)分成一个个的逻辑单元。 比如,不要一次将两个新特性PR出去。要添加的特性排好队,一个一个来。
+* 提交之前看一眼,`git diff --check`的空格一定要写对了
+* 确定你的代码能通过编译
+ * 布局: 确定`make keyboard:your_new_keymap` 不返回错误
+ * 键盘: 确定 `make keyboard:all` 不返回错误
+ * 核心代码: 确定 `make all` 不返回错误
+* 提交的信息尽量明确。第一行写点简短介绍(每行不多于70个英文字母), 第二行空着,第三行和后面就要写些必要的细节了。最好用英文写,比如:
+
+```
+Adjust the fronzlebop for the kerpleplork
+
+The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations.
+
+Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure.
+```
+
+## 文档
+
+想帮助Q酱当然是先看文档最简单了。找到这个文档哪里错了然后改正它对于你来说超级简单! 我们也对有写文档能力的人求贤若渴,如果你是对的人[点这个](#Q酱,我在哪能帮助你嘞?)!
+
+文档呢,都静静的放在`qmk_firmware/docs` 目录里, 也或者您想为网页做贡献的话也是可以的哦。
+
+在文档中附代码案例时, 先观察文档其他地方的命名规范。比如, 把enums的名字都改成像`my_layers`或者`my_keycodes`来防止名字不一致的enums被当作特务枪毙:
+
+```c
+enum my_layers {
+ _FIRST_LAYER,
+ _SECOND_LAYER
+};
+
+enum my_keycodes {
+ FIRST_LAYER = SAFE_RANGE,
+ SECOND_LAYER
+};
+```
+
+## 布局
+
+大多数QMK新手都从创建一个自己的布局开始。我们尽力保证布局规范宽松 (毕竟布局是个性的体现) 不过建议遵守以下准则,这样可以让别人更好理解你的代码
+
+* 用 [模板](documentation_templates.md)写个`readme.md`。
+* 所有的布局PR都会被squash, 如果你想知道你的提交是怎么被squash的那你就自己来吧
+* 不要把新特性和布局一起PR。可以分别PR他们
+* 布局文件夹就不要放`Makefile`了,这个操作都过时啦
+* 更新文件头部的copyrights(看`%YOUR_NAME%`那)
+
+## 键盘
+
+QMK的最终归宿是键盘。有些键盘是社区维护的,有一些是制作这些键盘的人维护的。`readme.md`会告诉你是谁维护了这个键盘,如果你对某个键盘有疑问,可以 [创建一个Issue](https://github.com/qmk/qmk_firmware/issues) 来问一问维护者。
+
+我们建议你按下面的来操作:
+
+* 用[模板](documentation_templates.md)写`readme.md`。
+* 提交数量尽量合理,不然我们可就要把你的PR给squash了。
+* 不要把新特性和新键盘一起PR。可以分别PR他们
+* 用父文件夹的名字命名 `.c`/`.h`文件, 比如`/keyboards/<kb1>/<kb2>/<kb2>.[ch]`
+* 键盘文件夹就不要放`Makefile`了,这个操作都过时啦
+* 更新文件头部的copyrights(看`%YOUR_NAME%`那)
+
+## Quantum/TMK 核心
+
+在您废寝忘食地开发Q酱新特性或者帮Q酱驱虫之前,一定要确保你的工作是有意义的。看看[了解QMK](understanding_qmk.md)你会对Q酱有更深的了解,这个文档将带你领略QMK的程序流程。现在你应该和维护团对谈谈来了解实现你想法的最佳方法了。一下渠道都可以:
+
+* [在Discord交流](https://discord.gg/Uq7gcHh)
+* [建立一个Issue](https://github.com/qmk/qmk_firmware/issues/new)
+
+新特性和BUG的修复影响所有键盘。开发组也在翻修QMK。所以,在实施重大返修之前一定要讨论一下。如果你在没有事先与维护团队沟通的情况下提交了一个PR,而且你的选择与维护团队的计划方向不符,那你可能要面临大改了。
+
+修复BUG或者开发新特性之前看看这个:
+
+* **默认不启用** - QMK运行的芯片多数内存有限,所以首要考虑的还应该是布局不要被破坏,于是特性默认是不启用的。你喜欢什么特性的话就打开它,如果你觉得有些特性应该默认开启或者你能帮助缩减代码,那就联系维护组吧。
+* **提交之前在本地编译** - 这个简直就是家喻户晓了,但是也确实需要编译啊! 我们的Travis系统会发现一切问题,但是自己编译一下可要比在线等快多了。
+* **注意版本和芯片平台** - 有那么几个键盘有支持不同配置甚至是不同芯片的版本。试着写一个能AVR和ARM两个平台运行的特性,或者在不支持的平台自动禁用。
+* **解释你的新特性** - 在`docs/`写个文档, 你可以创建新文档或者写到现有文档中。如果你不把它记录下来,其他人就无法从你的努力中获益。
+
+也可以看看以下建议:
+
+* 提交数量尽量合理,不然我们可就要把你的PR给squash了。
+* 不要把新特性、布局和键盘一起PR。可以分别PR他们。
+* 给你的特性写[单元测试](unit_testing.md)。
+* 你编辑的文件风格要一致,如果风格不明确或者是混搭风的,你就要先看看[代码规范](#代码规范)确认情况。
+
+## 重构
+
+为了保持QMK脉络清晰,Q酱打算深入规划重构一下自己,然后让合作者进行修改。如果你有重构的思路或建议[创建一个issue](https://github.com/qmk/qmk_firmware/issues), Q酱很乐意讨论一下怎么改进一下。
+
+# 行为守则对于我来说有何意义?
+
+我们的[行为守则](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md) 是说明您有责任尊重和礼貌地对待项目中的每个人,无论他们的身份如何。 如果你是我们行为准则所描述的不当行为的受害者,我们将站在你这边,并按照行为准则对施暴者进行适当谴责。
diff --git a/docs/zh-cn/custom_quantum_functions.md b/docs/zh-cn/custom_quantum_functions.md
new file mode 100644
index 0000000000..42ceba9cac
--- /dev/null
+++ b/docs/zh-cn/custom_quantum_functions.md
@@ -0,0 +1,490 @@
+# ζ̵Ĺ
+
+ںܶ˵ƻ̿ɲֻĵԷ㰴Ǹô򵥡϶ʵֱȼ򵥰ͺӵĹܡQMKעĹ, ǹ, ⣬ԶڲͬµΪ
+
+ҳٶκQMK֪ʶĶ[QMK](understanding_qmk.md)ڸIJⷢʲô
+
+## A Word on Core vs vs
+
+ǰqmk֯һνṹ
+
+* Core (`_quantum`)
+ * Keyboard/Revision (`_kb`)
+ * Keymap (`_user`)
+
+ÿһڶϼһ`_kb()` `_user()` ׺ ڼ/޶ʹ`_kb()`׺ڲֲʹ`_user()`׺
+
+ڼ/޶㶨庯ʱ`_kb()`ִκδǰȵ`_user()`DZҪģȻֲ㺯ͲҪá
+<!-- ⣺Ǿ䷭IJ̫-->
+# Զ
+
+ĿǰΪֹǸмΪ򴴽µļ롣ӴǶЩơ
+
+## һ¼
+
+һöٳȫҲǸֲΨһֵQMKûֱֵСṩһ`SAFE_RANGE`ꡣöʱ`SAFE_RANGE`֤ȡΨһļֵ
+
+
+öӡӵ`keymap.c`Ļڲ`FOO``BAR`ˡ
+
+```c
+enum my_keycodes {
+ FOO = SAFE_RANGE,
+ BAR
+};
+```
+
+## ΪΪ
+
+㸲һѴڰΪʱΪ¼ʱҪ`process_record_kb()``process_record_user()`ڼʵ¼ǰQMKá`true`QMKķʽ롣ԺܷչĹܶ滻`false` QMKȻͼ̧ǰ¼ˡ
+
+ij»ͷʱᱻá
+
+### process_record_user()`ʾʵ
+
+¡Զһ`FOO`ļΪڰ»سʱ
+
+```c
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case FOO:
+ if (record->event.pressed) {
+ // ʱЩʲô
+ } else {
+ // ͷʱЩʲô
+ }
+ return false; // ˼нһ
+ case KC_ENTER:
+ // »سʱ
+ if (record->event.pressed) {
+ PLAY_NOTE_ARRAY(tone_qwerty);
+ }
+ return true; // QMKس/ͷ¼
+ default:
+ return true; //
+ }
+}
+```
+
+### `process_record_*` ĵ
+
+* /޶: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)`
+* : `bool process_record_user(uint16_t keycode, keyrecord_t *record)`
+
+`keycode()`ڲ϶ģ`MO(1)`, `KC_L`, ȵȡ Ҫ `switch...case` Щ¼
+
+`record`ʵʰϢ
+
+```c
+keyrecord_t record {
+ keyevent_t event {
+ keypos_t key {
+ uint8_t col
+ uint8_t row
+ }
+ bool pressed
+ uint16_t time
+ }
+}
+```
+
+# LED
+
+qmkṩ˶ȡHID淶5LEDķ:
+
+* `USB_LED_NUM_LOCK`
+* `USB_LED_CAPS_LOCK`
+* `USB_LED_SCROLL_LOCK`
+* `USB_LED_COMPOSE`
+* `USB_LED_KANA`
+
+ӦLED״̬λλ
+ַԻLED״̬
+
+* ִͨ `led_set_user()`
+* ͨ `host_keyboard_leds()`
+
+## `led_set_user()`
+
+5LEDκһ״̬Ҫıʱ˺á˺ͨLED
+ʹ`IS_LED_ON(usb_led, led_name)``IS_LED_OFF(usb_led, led_name)`LED״̬
+
+!> `host_keyboard_leds()`ܻ`led_set_user()`ǰֵ
+
+### `led_set_user()`ʾʵ
+
+```c
+void led_set_user(uint8_t usb_led) {
+ if (IS_LED_ON(usb_led, USB_LED_NUM_LOCK)) {
+ writePinLow(B0);
+ } else {
+ writePinHigh(B0);
+ }
+ if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
+ writePinLow(B1);
+ } else {
+ writePinHigh(B1);
+ }
+ if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
+ writePinLow(B2);
+ } else {
+ writePinHigh(B2);
+ }
+ if (IS_LED_ON(usb_led, USB_LED_COMPOSE)) {
+ writePinLow(B3);
+ } else {
+ writePinHigh(B3);
+ }
+ if (IS_LED_ON(usb_led, USB_LED_KANA)) {
+ writePinLow(B4);
+ } else {
+ writePinHigh(B4);
+ }
+}
+```
+
+### `led_set_*`ĵ
+
+* /޶: `void led_set_kb(uint8_t usb_led)`
+* : `void led_set_user(uint8_t usb_led)`
+
+## `host_keyboard_leds()`
+
+᷵յLED״̬`led_set_*`֮ȡLED״̬ʱã[`matrix_scan_user()`](#ɨ).
+Ϊ˱ݣ`IS_HOST_LED_ON(led_name)``IS_HOST_LED_OFF(led_name)` ֱ꣬ӵúͼ`host_keyboard_leds()`
+
+## LED״̬
+
+һЩʵΪLED״̬ṩ˷ķ
+
+### Ergodox Boards
+
+Ergodoxʵṩ`ergodox_right_led_1`/`2`/`3_on`/`off()`ÿLED, Ҳ `ergodox_right_led_on`/`off(uint8_t led)` 򿪻رǡ
+
+⣬ʹ`ergodox_led_all_set(uint8_t n)`ָLEDȼÿLED`ergodox_right_led_1`/`2`/`3_set(uint8_t n)`ʹĻ`ergodox_right_led_set(uint8_t led, uint8_t n)`
+
+Ergodox boards ͬʱȼ`LED_BRIGHTNESS_LO`ȼ`LED_BRIGHTNESS_HI`(Ĭ).
+
+# ̳ʼ
+
+̳ʼм衣ǸȡҪʲô
+
+Ҫʼ˳г
+
+* `keyboard_pre_init_*` - ڴǰСЩҪǰеӲʼ
+* `matrix_init_*` - ڹ̼м䱻áʱӲѳʼδʼ
+* `keyboard_post_init_*` - ڹ̼󱻵á£ġƻ붼Է
+
+!> ڴ˵`keyboard_post_init_user`Ҫõĺ, ʱRGBƷ⡣
+
+## Ԥʼ
+
+뼫УUSBʼǰС
+
+֮󲻾þͱʼˡ
+
+ڴû˵,òΪҪӲijʼ
+
+ӲʼĻٺò(ʼLEDһ).
+
+### `keyboard_pre_init_user()`ʾʵ
+
+ڼ̼趨 B0, B1, B2, B3, B4 LEDš
+
+```c
+void keyboard_pre_init_user(void) {
+ // üԤʼ
+
+ // LEDΪģʽ
+ setPinOutput(B0);
+ setPinOutput(B1);
+ setPinOutput(B2);
+ setPinOutput(B3);
+ setPinOutput(B4);
+}
+```
+
+### `keyboard_pre_init_*` ĵ
+
+* /޶: `void keyboard_pre_init_kb(void)`
+* : `void keyboard_pre_init_user(void)`
+
+## ʼ
+
+⽫ھʼʱãijЩӲúú󣬵һЩܱʼǰ
+
+طõĶʱãӲ޹أҲλá
+
+
+### `matrix_init_*`ĵ
+
+* /޶: `void matrix_init_kb(void)`
+* : `void matrix_init_user(void)`
+
+
+## ̺ʼ
+
+Ǽ̳ʼеһijЩԣãΪʱӦöǽгʼ
+
+
+### `keyboard_post_init_user()`ʾʵ
+
+ʾгʼɺУRGBơ
+
+```c
+void keyboard_post_init_user(void) {
+ // úʼ
+ rgblight_enable_noeeprom(); // ʹRgb
+ rgblight_sethsv_noeeprom(180, 255, 255); // ɫõɫ(ɫ)
+ rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // ÿٺģʽ
+}
+```
+
+### `keyboard_post_init_*` ĵ
+
+* /޶: `void keyboard_post_init_kb(void)`
+* : `void keyboard_post_init_user(void)`
+
+# ɨ
+
+ܵĻҪ`process_record_*()`Զַ̣ʽӵ¼Уȷ벻Լ̲Ӱ졣Ȼڼ£бҪоɨ衣ЩҪرעܣΪÿٱ10Ρ
+
+### `matrix_scan_*`ʾʵ
+
+ӱʡˡhookһܼе֮ǰӦ㹻˽qmkڲṹԱûʾ±дҪ[һissue](https://github.com/qmk/qmk_firmware/issues/new)[Discordǽ](https://discord.gg/Uq7gcHh).
+
+### `matrix_scan_*` ĵ
+
+* /޶: `void matrix_scan_kb(void)`
+* : `void matrix_scan_user(void)`
+
+úÿξɨʱãMCUͬдҪΪкܶΡ
+
+ԶɨʱõҲԶ״̬(LEDƻĻ)ûҲ붨еĹܡ
+
+
+# /
+
+֧־ͿֹͨͣһƱﵽ""RGBƺͱǺܺõӡԽԼܺģҲ̷ζѡ
+
+: `suspend_power_down_*``suspend_wakeup_init_*`, ֱϵͳкͻʱá
+
+
+### suspend_power_down_user()suspend_wakeup_init_user()ʾʵ
+
+
+```c
+void suspend_power_down_user(void) {
+ rgb_matrix_set_suspend_state(true);
+}
+
+void suspend_wakeup_init_user(void) {
+ rgb_matrix_set_suspend_state(false);
+}
+```
+
+### / ĵ
+
+* /޶: `void suspend_power_down_kb(void)` `void suspend_wakeup_init_user(void)`
+* : `void suspend_power_down_kb(void)` `void suspend_wakeup_init_user(void)`
+
+# ı
+
+ÿıд롣ڲָʾԶ㴦á
+
+### `layer_state_set_*` ʾʵ
+
+ʹPlanckʾ [RGB](feature_rgblight.md)ʹ֮Ӧ
+
+```c
+uint32_t layer_state_set_user(uint32_t state) {
+ switch (biton32(state)) {
+ case _RAISE:
+ rgblight_setrgb (0x00, 0x00, 0xFF);
+ break;
+ case _LOWER:
+ rgblight_setrgb (0xFF, 0x00, 0x00);
+ break;
+ case _PLOVER:
+ rgblight_setrgb (0x00, 0xFF, 0x00);
+ break;
+ case _ADJUST:
+ rgblight_setrgb (0x7A, 0x00, 0xFF);
+ break;
+ default: // for any other layers, or the default layer
+ rgblight_setrgb (0x00, 0xFF, 0xFF);
+ break;
+ }
+ return state;
+}
+```
+### `layer_state_set_*` ĵ
+
+* /޶: `uint32_t layer_state_set_kb(uint32_t state)`
+* : `uint32_t layer_state_set_user(uint32_t state)`
+
+
+`״̬`ǻbitmask, [ָ](keymap.md#ֵIJ״̬)
+
+
+# 籣 (EEPROM)
+
+óڵıڼСЩñصEEPROM粻ʧ ÿ`eeconfig_read_kb``eeconfig_read_user`ȡ`eeconfig_update_kb``eeconfig_update_user`д롣ϣܹлĹܺ(лRGBָʾ⣬`eeconfig_init_kb``eeconfig_init_user`EEPROMĬֵ
+
+ӵIJֿǣкܶ෽ͨEEPROM洢ͷݣҲûַǡȷġÿֻһ˫(ֽ)ռ䡣
+
+סEEPROMдġдܸߣDzֻдEEPROMСдƵMCU̡
+
+* ӣôϣʹԣΪ൱ӡ
+
+### ʾʵ
+
+ãҶдʹû֡һӵĺкܶҪʵϣʹ˺ܶ
+
+
+keymap.cļУ´:
+```c
+typedef union {
+ uint32_t raw;
+ struct {
+ bool rgb_layer_change :1;
+ };
+} user_config_t;
+
+user_config_t user_config;
+```
+
+ϴ뽨һṹ壬ýṹԴ洢òдEEPROM㽫趨ΪڽṹȻ塣Ҫס`bool` ()ֵʹ1λ, `uint8_t`ʹ8λ, `uint16_t`ʹ16λԻϴʹã˳Ǵܻ鷳Ϊǻıддֵ
+
+ `layer_state_set_*`ʹ`rgb_layer_change`ʹ`keyboard_post_init_user``process_record_user`һС
+
+Ҫʹ`keyboard_post_init_userҪ`eeconfig_read_user()`ոմĽṹ塣ȻʹṹIJеĹܡ
+```c
+void keyboard_post_init_user(void) {
+ // òּľʼ
+
+ // EEPROMû
+ user_config.raw = eeconfig_read_user();
+
+ // ʹܣĬϲ
+ if (user_config.rgb_layer_change) {
+ rgblight_enable_noeeprom();
+ rgblight_sethsv_noeeprom_cyan();
+ rgblight_mode_noeeprom(1);
+ }
+}
+```
+ϺڶEEPROMúʹøĬϲRGBɫ"raw"ֵǴ"union"Ľṹתġ
+
+```c
+uint32_t layer_state_set_user(uint32_t state) {
+ switch (biton32(state)) {
+ case _RAISE:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); }
+ break;
+ case _LOWER:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); }
+ break;
+ case _PLOVER:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); }
+ break;
+ case _ADJUST:
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); }
+ break;
+ default: // Ĭϲ
+ if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); }
+ break;
+ }
+ return state;
+}
+```
+ֵʹʱıRGBơֵ, Ϊ`process_record_user`һ¼`RGB_LYR`ҪȷʹRGB룬ʹʾرգ뽫Ϊ
+```c
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+ switch (keycode) {
+ case FOO:
+ if (record->event.pressed) {
+ // ʱʲô
+ } else {
+ // ͷʱʲô
+ }
+ return false; // ˼Ľһ
+ case KC_ENTER:
+ // ڰ»سʱ
+ if (record->event.pressed) {
+ PLAY_NOTE_ARRAY(tone_qwerty);
+ }
+ return true; // QMKس/ͷ¼
+ case RGB_LYR: // underglowΪָʾʹá
+ if (record->event.pressed) {
+ user_config.rgb_layer_change ^= 1; // л״̬
+ eeconfig_update_user(user_config.raw); // EEPROMд״̬
+ if (user_config.rgb_layer_change) { // ״̬ʹ
+ layer_state_set(layer_state); // ô̸²ɫ
+ }
+ }
+ return false; break;
+ case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // еRGB (see quantum_keycodes.h, L400 Բο)
+ if (record->event.pressed) { //ʧָܲʾıҪ
+ if (user_config.rgb_layer_change) { // ʹʱ
+ user_config.rgb_layer_change = false; // ʧܣȻ
+ eeconfig_update_user(user_config.raw); // EEPROMд
+ }
+ }
+ return true; break;
+ default:
+ return true; //
+ }
+}
+```
+Ҫ`eeconfig_init_user`ԵEEPROMʱָĬֵ, ԶǿEEPROM`EEP_RST`[Bootmagic](feature_bootmagic.md)磬ҪĬRGBָʾĬֵ
+
+```c
+void eeconfig_init_user(void) { // EEPROM
+ user_config.raw = 0;
+ user_config.rgb_layer_change = true; // ҪĬʹ
+ eeconfig_update_user(user_config.raw); // EEPROMдĬֵ
+
+ // use the non noeeprom versions, ҪEEPROMдЩֵ
+ rgblight_enable(); // ĬʹRGB
+ rgblight_sethsv_cyan(); // Ĭɫ
+ rgblight_mode(1); // Ĭó
+}
+```
+
+ȻˡRGBָʾʱûһֱ棬¼̡ʹRGB룬ָʾʧܣˡ
+
+### 'EECONFIG' ĵ
+
+* /޶: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)``void eeconfig_update_kb(uint32_t val)`
+* : `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)``void eeconfig_update_user(uint32_t val)`
+
+`val` дEEPROMֵ`eeconfig_read_*`EEPROMһ32λ(˫)ֵ
+
+# Զ-ٽֵ(TAPPING_TERM)
+Ĭ,-ٽֵȫͳһģҲͨáڴû˵ܺáЩ£`LT`˵ʱ˫ܼ󣬿ΪЩļװסΪ˲ÿԶ룬ܿΪÿ`TAPPING_TERM`
+
+ʹܵĻ, Ҫ`config.h``#define TAPPING_TERM_PER_KEY`
+
+
+## `get_tapping_term`ʾʵ
+
+Ҫ޸Ļڼ`TAPPING TERM`,Ҫ`keymap.c`ļ´:
+
+```c
+uint16_t get_tapping_term(uint16_t keycode) {
+ switch (keycode) {
+ case SFT_T(KC_SPC):
+ return TAPPING_TERM + 1250;
+ case LT(1, KC_GRV):
+ return 130;
+ default:
+ return TAPPING_TERM;
+ }
+}
+```
+
+### `get_tapping_term` ĵ
+
+ƪ,Ҫquantum߼̼ĺֻҪûɡ