ARTICLE DETAIL

资讯详情

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

QMK 固件中 BINEPAD BNR1 旋钮的移植实战:双版本构建、编码器映射与 Bootloader 进入方式

QMK 固件中 BINEPAD BNR1 旋钮的移植实战:双版本构建、编码器映射与 Bootloader 进入方式 QMK 固件中 BINEPAD BNR1 旋钮的移植实战双版本构建、编码器映射与 Bootloader 进入方式【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmwareBINEPAD BNR1 是一款集旋转、按压、边按边转于一体的多功能 USB 旋钮外设在 QMK 固件 中以binepad/bnr1键盘目录提供完整的移植支持覆盖 ATMega32u4V1和 STM32F103V2两个硬件版本。本文基于该移植目录的 readme、键盘配置与默认 keymap 源码完整讲清 BNR1 在 QMK 中的构建方法、端口配置细节、旋钮按压 旋转双重输入的实现方式含编码器事件队列原理以及三种进入 bootloader 烧录固件的途径读完即可独立完成 BNR1 固件的编译与烧录。一、设备定位一个旋钮承载三种输入BNR1 的核心形态是一枚多功能旋钮multifunction knob其输入能力分为三类旋转rotate旋钮本体为旋转编码器通过两相正交信号产生方向事件QMK 将其映射为方向敏感的键码如音量加减、鼠标滚轮按压press旋钮中央是一块物理按键在 QMK 中体现为 1x1 键盘矩阵的一个键位可使用全部普通键码与高级键码如LT、MO边按边转rotate while pressed按压状态会切换图层旋转在该图层下被重新映射——这正是默认 keymap 中按住旋钮时旋转变为鼠标滚轮的实现基础。该外设由 Binepad 维护硬件分为两代对应仓库中两个不同的 target 目录硬件版本MCUTarget 路径说明BNR1 / BNR1 R2V1ATMega32u4keyboards/binepad/bnr1/v1/初代硬件Atmel DFU bootloaderBNR1 V2STM32F103keyboards/binepad/bnr1/v2/第二代硬件stm32duino bootloader两代硬件在 QMK 中的配置独立存放各自的keyboard.json但共用同一份默认 keymap见 keymaps/default。二、构建固件两条 make 命令在配好 QMK 构建环境make 工具链、交叉编译器之后BNR1 的固件构建命令由版本决定# V1 硬件ATMega32u4 make binepad/bnr1/v1:default # V2 硬件STM32F103 make binepad/bnr1/v2:default其中binepad/bnr1/v1是 target对应keyboards/binepad/bnr1/v1/目录下的硬件配置default是 keymap 名对应 keymaps/default。首次接触 QMK 的开发者可参考仓库文档 getting_started_make_guide.md 了解 make 工作流以及 newbs.md 的完整新手指南。三、固件能力info.json 声明的功能集键盘级别的公共元数据在 info.json 中声明可直接读出该外设启用/禁用的 QMK 特性{ manufacturer: Binepad, keyboard_name: BNR1, maintainer: Binpad, features: { bootmagic: true, extrakey: true, mousekey: true, nkro: false, encoder: true }, usb: { vid: 0x4249 }, community_layouts: [ortho_1x1], layouts: { LAYOUT_ortho_1x1: { layout: [ {matrix: [0, 0], x: 0, y: 0, w: 2, h: 2} ] } } }逐项解读encoder: true启用 QMK 编码器支持这是旋转能力的来源mousekey: true启用鼠标键支持。默认 keymap 的第二图层把旋转映射为MS_WHLD/MS_WHLU鼠标滚轮下/上依赖该特性extrakey: true启用扩展键KC_MUTE等多媒体键bootmagic: true启用 Bootmagic——即按住某个键插入 USB 即进入 bootloader与下文 Bootloader 章节对应nkro: false显式关闭 NKRO。BNR1 只有 1 个矩阵键位全键无冲无意义关闭可节省空间usb.vid: 0x4249厂商 ID 为0x4249对应 ASCII BI两代硬件共用各自在keyboard.json中定义不同的 PIDlayouts布局为 1x1 正交矩阵LAYOUT_ortho_1x1矩阵位置[0,0]占据 2u×2u 的旋钮面积。四、硬件端口配置两代 keyboard.json 逐项对照每个 target 的硬件差异全部集中在各自的keyboard.json中这是 QMK 的数据驱动配置方式——不写 C 代码即可描述引脚映射。V1ATMega32u4keyboards/binepad/bnr1/v1/keyboard.json{ bootloader: atmel-dfu, processor: atmega32u4, diode_direction: COL2ROW, usb: { pid: 0x4231, device_version: 1.0.0 }, build: { lto: true }, matrix_pins: { cols: [B0], rows: [E6] }, encoder: { enabled: true, rotary: [ {pin_a: D6, pin_b: D7} ] } }要点bootloader 为atmel-dfu烧录走 DFU 协议与 readme 中三种进入 bootloader 的方式配套矩阵按键引脚单列B0、单行E6即旋钮按压键接在 PB0列输入与 PE6行驱动之间diode_direction为COL2ROW列接低侧二极管、行驱动符合 QMK 标准的行/列扫描模型编码器两相引脚pin_a: D6、pin_b: D7QMK 编码器驱动据此做正交解码判断顺时针/逆时针build.lto: true启用链接期优化LTO对 AVR 这类空间紧张的 MCU 有助于压缩固件体积。V2STM32F103keyboards/binepad/bnr1/v2/keyboard.json{ bootloader: stm32duino, processor: STM32F103, diode_direction: COL2ROW, usb: { pid: 0x4241, device_version: 2.0.0 }, matrix_pins: { cols: [A15], rows: [A8] }, encoder: { enabled: true, rotary: [ {pin_a: B3, pin_b: B4} ] } }与 V1 的差异bootloader 换为stm32duinoUSB PID 由0x4231改为0x4241设备版本升至2.0.0矩阵键位改接A15/A8编码器改接B3/B4。注意两代硬件仅 PID 不同V10x4231/ V20x4241主机侧可通过该值区分具体硬件代数。五、默认 keymap按压切层 编码器双图层映射默认 keymap 完整继承了旋转、按压、边按边转三合一的设计源码见 keymap.cenum { _L0, _L1 } keyboard_layers; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] { [_L0] LAYOUT_ortho_1x1( LT(_L1, KC_MUTE) ), [_L1] LAYOUT_ortho_1x1( _______ ) }; #if defined(ENCODER_MAP_ENABLE) const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] { [_L0] { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, [_L1] { ENCODER_CCW_CW(MS_WHLD, MS_WHLU) } }; #endif行为拆解L0 层LT(_L1, KC_MUTE)使旋钮按压键兼具两种功能——短按发送静音键KC_MUTE按住不放则切换到 L1 层LT 即 Layer TapQMK 标准高级键码L1 层矩阵键位为透明键_______按压本身在 L1 不再产生动作L1 完全由按住维持encoder_map为每层各定义一组方向键码ENCODER_CCW_CW(ccw, cw)宏把两个参数分别绑定到逆时针/顺时针方向。L0 下逆时针/顺时针对应KC_VOLD/KC_VOLU音量减/加L1 下对应MS_WHLD/MS_WHLU鼠标滚轮下/上。由此边按边转即鼠标滚轮的效果在默认 keymap 中天然成立。encoder_map的声明依赖编译开关它包裹在#if defined(ENCODER_MAP_ENABLE)中而该开关正是由 rules.mk 打开的ENCODER_MAP_ENABLE yesENCODER_MAP_ENABLE打开后编码器旋转不再调用普通的encoder_update_kb()而是被转换为一对按下/抬起动作事件详见下节。六、原理印证QMK 编码器事件队列与动作执行理解encoder_map为何能实现方向敏感键码需要看 QMK 的编码器核心实现 quantum/encoder.c 与 quantum/encoder.h。1事件入队编码器硬件层如 drivers/encoder/encoder_quadrature.c 的正交解码驱动负责读引脚、判方向判出索引 方向后调用encoder_queue_event(index, clockwise)写入环形队列。队列结构在 quantum/encoder.h 中定义typedef struct encoder_event_t { uint8_t index : 7; uint8_t clockwise : 1; } encoder_event_t; typedef struct encoder_events_t { uint8_t enqueued; uint8_t dequeued; uint8_t head; uint8_t tail; encoder_event_t queue[MAX_QUEUED_ENCODER_EVENTS]; } encoder_events_t;BNR1 只有 1 个编码器NUM_ENCODERS为 1队列深度默认至少为MAX(4, NUM_ENCODERS_MAX_PER_SIDE 1)足以缓冲快速旋转产生的连续事件。2动作执行主循环中encoder_task()驱动事件消费quantum/encoder.c 的encoder_handle_queue()展示了两种模式的分叉ENCODER_MAP_ENABLE开启BNR1 默认 keymap 正是此模式每个旋转事件被展开为按下 抬起两次action_exec()调用且方向由MAKE_ENCODER_CW_EVENT/MAKE_ENCODER_CCW_EVENT区分action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, true) : MAKE_ENCODER_CCW_EVENT(index, true)); #if ENCODER_MAP_KEY_DELAY 0 wait_ms(ENCODER_MAP_KEY_DELAY); #endif action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, false) : MAKE_ENCODER_CCW_EVENT(index, false));即旋转一格 一次完整的按键 down/up 序列方向决定走哪一列encoder_map键码——这正是 L0 层KC_VOLD/KC_VOLU与 L1 层MS_WHLD/MS_WHLU的生效路径。注释中特别提到ENCODER_MAP_KEY_DELAY的延迟是为了兼容 Windows 对按键事件的时序要求默认取TAP_CODE_DELAY见 quantum/encoder.c未开启时退化为调用encoder_update_kb(index, clockwise)回调由键盘/用户代码自行处理方向。此外should_process_encoder()在默认实现中返回is_keyboard_master()为分体键盘预留了从机侧不处理编码器事件的钩子BNR1 是单 MCU 设备该判断恒为真从源码结构看这一抽象对外设类键盘无额外负担。3方向宏的约定ENCODER_CCW_CW(ccw, cw)在 quantum/encoder.h 中展开为{(cw), (ccw)}——注意宏内部做了参数交换因此写法是逆时针参数在前、顺时针参数在后而存储顺序与NUM_DIRECTIONS固定为 2的方向索引对齐。七、进入 Bootloader 的三种方式编译完成后需要烧录。BNR1 提供三种进入 bootloader 的途径见 readmeBootmagic reset推荐按住旋钮按压键的同时插入 USB 线缆。此方式依赖info.json中启用的bootmagic特性无需记忆任何键码物理复位键轻按 PCB 底面的 RESET 按钮键码触发在 keymap 中为旋钮映射QK_BOOT别名RESET键码后直接按下。进入 bootloader 后V1 的 Atmel DFU 与 V2 的 stm32duino bootloader 均以 HID DFU 形式呈现使用 QMK 构建后提示的make ...:flash或对应 DFU 烧录流程即可完成写入。日常使用 Bootmagic 即可无需拆机寻找复位键。八、小结与延伸阅读BNR1 在 QMK 中的移植是一个典型的极小矩阵 编码器外设范例1 个矩阵键位承载全部按键语义LT切层实现边按边转ENCODER_MAP_ENABLEencoder_map实现方向敏感的逐层映射而两代硬件的差异完全由keyboard.json数据驱动地表达。相关可继续深入的文件keyboards/binepad/bnr1/readme.md设备 readme 原文构建命令与 Bootloader 方式keyboards/binepad/bnr1/info.json特性开关、VID 与布局定义keyboards/binepad/bnr1/v1/keyboard.json / keyboards/binepad/bnr1/v2/keyboard.json两代硬件引脚配置keyboards/binepad/bnr1/keymaps/default/keymap.c默认 keymap 与编码器映射quantum/encoder.c / quantum/encoder.h编码器事件队列与动作执行核心docs/feature_layers.md、docs/quantum_keycodes.md图层机制与高级键码LT、RESET参考【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表