news 2026/10/15 15:50:59

瀚文 HelloWord-Smart Keyboard 开源模块化机械键盘全解析:硬件架构、键盘固件与 Dynamic 力反馈模块实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
瀚文 HelloWord-Smart Keyboard 开源模块化机械键盘全解析:硬件架构、键盘固件与 Dynamic 力反馈模块实现
  • 硬件开发
  • 嵌入式
  • 智能硬件
  • 固件

【免费下载链接】HelloWord-Keyboard

项目地址:https://gitcode.com/gh_mirrors/he/HelloWord-Keyboard
点击查看免费下载

本文以仓库根目录的 README.md 为骨架,结合2.Firmware下的双固件源码、1.Hardware原理图清单、3.Software上位机插件等仓库资源,系统讲解「瀚文」智能键盘的模块化硬件架构、基于移位寄存器的高速按键扫描与多层键位映射方案、对称延迟独立滤波算法、双 ReportID 的 HID 协议、SPI-DMA 驱动的总线式 RGB,以及 Dynamic 组件中基于 FOC 的力反馈旋钮实现。读完本文,你可以完整理解该开源项目的目录结构与设计取舍,并掌握在源码层面二次开发、改配列、加灯效、扩展 APP 的具体入口。

1. 项目定位:一把为“自己”设计的多功能模块化机械键盘

瀚文(HelloWord-Smart Keyboard)是一把面向个人使用需求设计的多功能、模块化机械键盘:左侧的多功能场景交互模块可整体替换成各种自定义组件,默认搭载的是带电子墨水屏与FOC 力反馈旋钮的Dynamic 组件;键盘本体与模块均使用基于 ARM Cortex-M 芯片的自研固件;本体采用移位寄存器实现优化按键扫描电路;模块与键盘本体既可以单独使用,也可以通过串口协议相互通信、相互调用。

仓库开源的资料包括:

  • 瀚文本体硬件设计的 10 块 PCB 设计源文件(提供立创 EDA 专业版格式);
  • 外壳设计结构文件(3D 模型,支持 3D 打印);
  • 键盘本体的固件源码(相对完善);
  • Dynamic 组件的固件源码(框架已完成,更多 APP 扩展 WIP);
  • 键盘二次开发 SDK(开发中)。

2. 仓库目录结构与开源资料总览

仓库顶层目录划分清晰,各目录职责如下:

目录内容说明
1.Hardware全部电路原理图 PDF、PCB 工程链接立创 EDA 专业版格式,另含 Gerber 光绘文件
2.Firmware双固件源码工程、预编译 bin含.ioc工程文件,可用 STM32CubeMX 重新生成
3.Software上位机软件(墨水屏图片工具、SignalRGB 插件)视频中演示的傻瓜化改图工具所在目录
4.ToolsST-LINK Utility、Zadig、HID Descriptor Tool 等烧录、装驱动、调试 HID 描述符的三方工具
5.3D Model外壳结构件 STL / STEP 模型分为“瀚文基础版”与“瀚文扩展版”两套
5.Docs芯片 Datasheet、HID 用途表、项目图片参考资料

2.1 硬件部分:10 块 PCB 各司其职

1.Hardware中一共有 10 块板子,按功能划分如下:

  • HelloWord-Keyboard:主键盘 PCB,控制器为 STM32F103,可配合底座单独使用,提供常规按键输入功能,带全按键独立 RGB 灯;
  • HelloWord-Ctrl:左侧 Dynamic 组件 PCB,控制器为 STM32F405,可配合底座单独使用,提供 FOC 力反馈旋钮、电子墨水屏显示、OLED 显示、RGB 灯等功能;
  • HelloWord-Connector:主键盘用于连接底座的触点 PCB,通过 FFC 排线与键盘 PCB 连接;
  • HelloWord-Connector-Ctrl:Dynamic 组件用于连接底座的触点 PCB,通过 FFC 排线与 Dynamic 组件 PCB 连接;
  • HelloWord-Encoder:磁编码器 PCB,用于对无刷电机进行位置反馈,需要配合一个径向充磁的永磁铁工作;
  • HelloWord-Hub1:底座上扩展出的两个额外 USB-A 接口转接 PCB,通过 FFC 排线和 TypeC 接口板连接;
  • HelloWord-Hub2:底座上扩展出的两个额外 USB-A 接口母座 PCB,预留 USB3.0 母座和引脚,目前只使用到 2.0 接口,未来可升级到 USB3.0 HUB;
  • HelloWord-TypeC:底座上用于连接电脑的 TypeC 接口 PCB,板载电源充电管理芯片与 USB-HUB 芯片,通过 FFC 排线连接其余模块;
  • HelloWord-OLED:Dynamic 组件上 OLED 屏幕的最小驱动电路及转接板;
  • HelloWord-TouchBar:可选电容触摸条模块 PCB,使用 6 按键电容触摸芯片组成线性感应阵列,通过 FFC 排线与主键盘 PCB 连接。

硬件演进备注:2022.8.20 更新后,所有能在立创直接下单的元器件都已改成对应封装,方便直接配置 BOM;2022.8.22 起补全了全套 STEP 格式 3D 模型(含定位板)。早期原理图仍存在个别未修复 bug(如视频中出现的飞线),后续新版 PCB 打样验证后会更新。

2.2 固件部分:两个 STM32HAL 工程

2.Firmware中提供两个主要工程,均基于STM32HAL 库实现,并各自附带.ioc文件(HelloWord-Keyboard-fw.ioc、HelloWord-Dynamic-fw.ioc),可用 STM32CubeMX 打开后生成 Keil 或 STM32CubeIDE 工程,也可以用 CLion / STM32CubeIDE 直接编译下载:

  • HelloWord-Keyboard-fw:主键盘固件,主要实现基于硬件 SPI 和移位寄存器的高速按键扫描、基于硬件 SPI & DMA 的总线式 RGB 灯控制、HID 高速设备键盘枚举与报文协议、非易失存储配置、多层按键映射等功能;
  • HelloWord-Dynamic-fw:Dynamic 组件固件,主要实现基于 FOC 的电机控制、可配置触感封装类、电子墨水屏驱动、OLED 驱动、USB 全速复合设备枚举和通信协议、RGB 灯控制等功能。

_Release文件夹内是预编译好的 bin 固件(HelloWord-Dynamic-fw.bin、HelloWord-Keyboard-fw.bin、Test-Dynamic-fw.bin),可以用ST-Link Utility或 STM32CubeProgrammer 直接下载到芯片。其中Test-Dynamic-fw.bin为测试版固件:烧录到模块后可体验多种不同力反馈的滚轮效果,每次上电都会校准电机(校准失败需重新上电,正式使用时只需校准一次),模块上两个按键可以循环切换不同力反馈模式。

3. 硬件架构:扩展坞底座 + 键盘输入模块 + 多功能交互模块

瀚文的结构包含三大部分:扩展坞底座、键盘输入模块和可替换的多功能交互模块。键盘输入模块与多功能交互模块通过若干接触式触点连接在扩展坞底座顶部;键盘本体则采用标准客制化键盘的层叠结构设计(减震棉、PCBA、定位板、轴下垫等),整体为 75 键布局,结构设计基于 Xikii 的 S98 修改而来,有其他配列需求的用户可以自行修改 PCB 与固件适配。

3.1 芯片选型与设计约束

器件选型选型考量与可替换性
键盘主控STM32F103CBT6实际上 C8T6 也可以,但 CBT6 Flash 大一倍、性价比更高;固件基本基于 HAL 库,可替换为 STM32 系列任意芯片,前提是具备 2 个 SPI(分别用于按键扫描与 RGB 驱动)和 1 个全速 USB
组件主控STM32F405因手边芯片较多而选用,理论上可替换为更便宜的 F1 系列;需具备 1 个高级定时器(PWM 生成)、2 个硬件 SPI(编码器 + 墨水屏)、1 个 I2C(OLED)、1 个全速 USB
磁编码器AS5047P性能很好的常用磁编码芯片但成本略高,可替换为 MT6816 等更便宜型号(需同步修改固件驱动)
按键扫描74HC165国产零售约 0.5 元/片,一片驱动 8 个按键,按键数按需串联;项目扫描频率 4MHz,国产 16MHz 芯片绰绰有余
电容触摸XW06A(6 通道)对 PCB 感应盘设计有一定要求,仓库已提供设计好的 PCB;读取方式与普通按键无异,同样经 74HC165 扫描读取
电机驱动FD8288Q 栅极驱动器从作者此前开源的控制驱动器方案移植,无需电流传感器即可做 FOC 控制

3.2 电机选型与力反馈组件

Dynamic 组件使用的是 2204 尺寸的无刷电机(二手电机,当前可能不好购买,可换类似尺寸的无刷电机),参数上要求KV 值尽量低、最好在 200 左右。电机需要在转子上手动安装一个径向充磁的永磁体用于编码器定位,不同型号的电机需要对 FOC 参数进行相应调整。烧录方面,PCB 与外壳上均预留了 SWD 调试口,可用 JLink / STLink 等调试器烧录;作者后续计划放出可通过 USB 口直接升级固件的 Bootloader。

4. 键盘固件核心机制源码解析

主键盘固件位于 2.Firmware/HelloWord-Keyboard-fw/HelloWord,核心类是HWKeyboard(hw_keyboard.h / hw_keyboard.cpp),由 UserApp/main.cpp 以 1kHz 定时器回调驱动整条扫描-滤波-映射-上报流水线。

4.1 移位寄存器按键扫描:PCB 走线与扫描顺序解耦

键盘使用 11 片 74HC165 串联(IO_NUMBER = 11 * 8 = 88),固件通过硬件 SPI(hspi1,4MHz)以“锁存(Latch)→ 移位读入 → 采样(Sample)”的方式一次性读回 88 个 IO 状态。核心逻辑在 hw_keyboard.cpp 的ScanKeyStates():

uint8_t* HWKeyboard::ScanKeyStates() { memset(spiBuffer, 0xFF, IO_NUMBER / 8 + 1); PL_GPIO_Port->BSRR = PL_Pin; // Latch spiHandle->pRxBuffPtr = (uint8_t*) spiBuffer; spiHandle->RxXferCount = IO_NUMBER / 8 + 1; __HAL_SPI_ENABLE(spiHandle); while (spiHandle->RxXferCount > 0U) { if (__HAL_SPI_GET_FLAG(spiHandle, SPI_FLAG_RXNE)) { (*(uint8_t*) spiHandle->pRxBuffPtr) = *(__IO uint8_t*) &spiHandle->Instance->DR; spiHandle->pRxBuffPtr += sizeof(uint8_t); spiHandle->RxXferCount--; } } __HAL_SPI_DISABLE(spiHandle); PL_GPIO_Port->BRR = PL_Pin; // Sample return scanBuffer; }

扫描结果为按移位顺序排列的位图 buffer,每一位代表一个按键。这带来两个关键优势:其一,扫描频率极高(4MHz SPI 下单次扫描约 40us);其二,后续滤波与重映射都可以用位运算高效完成。

4.2 多层按键映射 keyMap:改配列只改一张表

为了充分发挥移位寄存器扫描方案的优势,固件将PCB Layout 走线与按键扫描顺序解耦,通过软件重映射:PCB 中按键的连接可以是任意的,走完线后在 hw_keyboard.h 的keyMap[KEYMAP_NUM][IO_NUMBER]中指定映射即可。

keyMap是一个二维数组:

  • 第 0 层(特殊层):负责把 PCB 按键的随机布局(按 74HC165 连接顺序编号)映射到键盘标准按键布局,数组元素填写的是扫描序号数字;
  • 第 1、2、3、4… 层(自定义层):负责把标准按键布局映射到任意布局,可直接使用枚举按键名(如RIGHT_ALT、F1),无需再记数字编号。

以 README 中的例子说明:原理图中某个按键在 PCB 上位于任意位置,但按 74HC165 连接顺序(即移位扫描顺序)是第 10 颗,因此编号为9(从 0 开始)。如果实际 PCB 把它放在了右边 Alt的位置,那么先查第 1 层(标准布局)中RIGHT_ALT的序号是76,于是在第 0 层映射中把第 76 号变量填成 9。

固件中通过keyboard.Remap(_layer)函数来启用某一层映射,例如keyboard.Remap(2)即使用第 2 层。Remap()的实现(hw_keyboard.cpp)分两步:

  1. 先用第 0 层把扫描位图重排为“标准键盘位图”(remapBuffer);
  2. 再用指定层把标准位图映射为 HID 键码并写入hidBuffer,负值的修饰键码(LEFT_CTRL=-8 … RIGHT_GUI=-1)会被解析到修饰键位,FN = 1000这类特殊码则用于触发层切换等逻辑。

在 main.cpp 的 1kHz 定时器回调中,实际映射逻辑是keyboard.Remap(keyboard.FnPressed() ? 2 : 1)——按住 FN 时自动切到第 2 层。仓库当前固件内置了 5 层keyMap(含 0 层),默认键盘为 82 键(KEY_NUMBER = 82),另加 6 个触摸条 IO(TOUCHPAD_NUMBER = 6)与 104 颗灯珠(LED_NUMBER = 104)。

因此,想修改键盘配列时只需:在原理图上增删几个串联的 74HC165 → PCB 随意走线 → 在代码中增删第 0 层映射的数字条目 → 按需修改后续各层即可。

4.3 对称延迟独立滤波:兼顾延迟与稳定性的位运算方案

固件对每个按键独立滤波,且实现非常高效——毕竟 1kHz 的报文、每个报文期间至少扫描两次按键,意味着每秒钟需要执行1000 * 2 * 按键数目次滤波。基本原理是:按键抖动源于按下后高低电平的反复横跳,电平稳定时间一般只有几十微秒(注意这与可能长达数毫秒的按键触发时间不同)。QMK 文档把滤波方法分为 Eager/Defer、对称/非对称等类别,其中“对称延迟全局滤波”是对所有按键做同等滤波、等全部按键稳定后再提交数据;而“激进滤波”虽然触发延迟低,但对噪声敏感、容易误触发。

瀚文固件采用的是对称延迟独立滤波(ApplyDebounceFilter,hw_keyboard.cpp):对每个按键做两次检测,若第一次检测到按键变化,则相隔 N 微秒(参数可配置,大于按键典型抖动时间即可,默认100us)再检测一次,两次结果一致才判定按下。这样既确保按键确实发生了变化,又不会重复触发,兼顾延迟与稳定性:

void HWKeyboard::ApplyDebounceFilter(uint32_t _filterTimeUs) { memcpy(debounceBuffer, spiBuffer, IO_NUMBER / 8 + 1); DelayUs(_filterTimeUs); ScanKeyStates(); uint8_t mask; for (int i = 0; i < IO_NUMBER / 8 + 1; i++) { mask = debounceBuffer[i] ^ spiBuffer[i]; spiBuffer[i] |= mask; } }

关键技巧在于整个过程用异或运算高效处理:mask = 两次扫描结果异或,恰好标记出发生了变化的位;由于扫描 buffer 天然是“每位一个按键”的位图结构,一次异或就能同时处理 8 个按键,滤波效率极高。

4.4 HID 描述符:双 ReportID 的全键无冲键盘

HID 报告描述符定义在 usbd_custom_hid_if.c,共配置了两个 ReportID:

  • ReportID 1:标准键盘报告(Key Codes),报告内是 8 位修饰键位图 + 120 位按键位图(Report Count 0x78),即120 键全键无冲(NKRO)的 bitmap 方案,同时包含一个 5 位 LED 输出报告(Num Lock / Caps Lock / Scroll Lock 等指示);
  • ReportID 2:RAW HID(Usage Page 0xFFC0 / Usage 0x0C00),32 字节双向输入输出,预留用于后续与上位机改键软件通信。

固件侧对应 hw_keyboard.cpp 的GetHidReportBuffer(_reportId):ReportID 1 返回主键码缓冲,ReportID 2 返回 RAW 缓冲。键盘枚举基于 STM32 USB 设备库的 CustomHID 类(Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID)。

更新说明中的一条重要修正:将CUSTOM_HID_EPOUT_ADDR = 2,并把HID_RxCpltCallback移到CUSTOM_HID_OutEvent_FS中(原位置可能导致 while 循环内无法发送 report)。

4.5 RGB 灯效:SPI-DMA 模拟 WS2812B 单总线时序

键盘使用单总线的 WS2812B 系列灯珠,一根线即可串联大量 RGB。固件在 hw_keyboard.cpp 中实现了SPI-DMA 模拟时序:把每个 RGB 位编码为 SPI 字节(WS_HIGH = 0xFE/WS_LOW = 0xE0),通过 DMA 高速搬运到 LED 上,获得超高刷新率:

void HWKeyboard::SyncLights() { while (isRgbTxBusy); isRgbTxBusy = true; HAL_SPI_Transmit_DMA(&hspi2, (uint8_t*) rgbBuffer, LED_NUMBER * 3 * 8); while (isRgbTxBusy); isRgbTxBusy = true; HAL_SPI_Transmit_DMA(&hspi2, wsCommit, 64); // 复位帧 }

设置灯效的公开接口是keyboard.SetRgbBufferByID(i, color)(写入 RGB 缓冲并做位编码)加keyboard.SyncLights()(DMA 发送)。主循环中的默认 demo 灯效(色彩轮询渐变)代码如下:

while (true) { /*---- This is a demo RGB effect ----*/ static uint32_t t = 1; static bool fadeDir = true; fadeDir ? t++ : t--; if (t > 250) fadeDir = false; else if (t < 1) fadeDir = true; for (uint8_t i = 0; i < HWKeyboard::LED_NUMBER; i++) keyboard.SetRgbBufferByID(i, HWKeyboard::Color_t{(uint8_t) t, 50, 0}); /*-----------------------------------*/ // Send RGB buffers to LEDs keyboard.SyncLights(); }

添加自己的灯效时,只需替换循环内的 RGB 写入逻辑即可;注意SetRgbBufferByID内部会把蓝色分量下限钳制到 1(if (_color.b < 1) _color.b = 1;),避免出现连续的 0 位导致 WS2812B 协议时序错误。

上位机控制协议(README 更新说明中明确给出):report 包大小33 字节,前三个字节依次为:

  1. reportid(本项目为2,对应 RAW HID 通道);
  2. 控制命令(0xAC= 开启上位机控制,0xBD= 关闭上位机控制);
  3. report 包次序(一个包最多传 10 个 RGB 值,需要多包拼接,从 0 开始计数)。

后 30 字节为 RGB 值(每灯 3 字节)。对应接收处理在 main.cpp 的HID_RxCpltCallback中:收到0xBD关闭软件控制、恢复固件内置灯效;收到0xAC则按pageIndex(_data[2])把 10 个灯一页地写入 RGB 缓冲,超出LED_NUMBER即结束本轮同步。

4.6 非易失存储:用片内 Flash 模拟 EEPROM

主键盘固件实现了基于片内 Flash 的“模拟 EEPROM”,用于持久保存配置(如键位映射)。实现位于 HelloWord/Utils/Memory/random_flash_utils.cpp:在 Flash 末尾页开辟一段区域,按 8 字节对齐缓存,写入时先擦除整页再以 double-word 为单位编程(EEPROMBufferFlush)。配置结构体KeyboardConfig_t定义在 UserApp/configurations.h(含configStatus状态机、serialNum、keyMap[128]),启动时在 main.cpp 中eeprom.Pull(0, config)拉取,校验失败则写入默认配置。

5. Dynamic 组件固件:FOC 力反馈旋钮与多任务软件架构

Dynamic 组件固件位于 2.Firmware/HelloWord-Dynamic-fw,基于FreeRTOS(CMSIS-RTOS V2)与 STM32F405 构建。入口 UserApp/main.cpp 创建了三个任务:

  • ControlLoopTask(osPriorityRealtime,最高优先级):挂载 FOC 电机驱动与编码器后,在 5ms 定时器中断(Timer timerCtrlLoop(&htim7, 5000))通过vTaskNotifyGiveFromISR通知下运行knob.Tick(),即电机控制主循环;
  • OledTask:驱动 OLED(SSD1306,经 I2C,见 BSP/u8g2)与电子墨水屏(BSP/eink/eink_290_bw.cpp,128×296 黑白屏),并刷新 RGB;
  • peripheralTask:轮询模块上两个按键(KEY_A / KEY_B),每次按下即切换KnobSimulator的模式(6 种模式循环切换)。

5.1 FOC 电机控制框架

电机控制代码位于 Ctrl,结构清晰:

  • Ctrl/Motor/motor.cpp(Motor类):提供TORQUE / VELOCITY / ANGLE / VELOCITY_OPEN_LOOP / ANGLE_OPEN_LOOP五种控制模式,内嵌电流环、速度环、角度环三级 PID(PidController,Ctrl/Motor/pid.h)与低通滤波器(Ctrl/Motor/lowpass_filter.h);
  • Ctrl/Sensor/Encoder/Instances/encoder_as5047.cpp:AS5047P 磁编码器 SPI 驱动,带偶校验位计算与 14 位原始数据解析;
  • Ctrl/Driver/Instances/driver_fd6288q.cpp:FD6288Q 栅极驱动器(三相 PWM 输出),方案无需电流传感器,属于无感(开环电流)FOC 简化实现;
  • Ctrl/Signal/button_base.cpp:按键基础类。

5.2 KnobSimulator:六种可配置力反馈触感

Ctrl/Motor/knob.h 中的KnobSimulator把“力反馈触感”抽象为 6 种模式:

模式控制模式效果
MODE_DISABLE关闭电机旋钮自由转动,无阻力
MODE_INERTIAVELOCITY惯性/阻尼模拟,甩动后按速度滑行
MODE_ENCODERANGLE数码编码器手感,按encoderDivides = 12等分角度逐格回弹
MODE_SPRINGANGLE弹簧回中,转动后自动归位
MODE_DAMPEDVELOCITY + 限位带限位(limitPositionMax = 5.1/limitPositionMin = 3.3)的阻尼手感,到边界变为角度保持
MODE_SPINVELOCITY持续匀速旋转

模式切换的触感参数(PID 增益、扭矩限制、目标位置/速度)在 knob.cpp 的SetMode中逐一配置,例如MODE_ENCODER使用角度环pidAngle = {p:100, i:0, d:3.5}、扭矩上限 1.5V;MODE_INERTIA则把速度环pidVelocity.p设为 0.1 并在Tick()中按“速度突变超过阈值才跟手”的方式更新目标速度。这正是Test-Dynamic-fw.bin测试固件让用户现场体验的效果来源。

5.3 通信协议:fibre 数据帧 + ASCII 命令

Dynamic 组件支持 USB 全速复合设备(CDC 虚拟串口 + UART + 预留 CAN)通信,底层基于 BSP/fibre 的流式协议:帧头0xAA、CRC-8(多项式 0x37)/ CRC-16-DNP(多项式 0x3d65)校验、endpoint 寻址、RX 缓冲 128 字节、TX 缓冲 32 字节,并提供流/包双向转换器(StreamToPacketSegmenter、PacketBasedStreamSink,protocol.hpp)。上层再封装 ASCII 命令协议(UserApp/protocols/ascii_protocol.cpp),通过Respond(...)统一回包(可选追加异或校验*checksum+ CRLF),扩展自定义命令只需在OnAsciiCmd中按帧首字符分发即可——这也正是“模块与键盘本体通过串口协议相互通信和调用”的实现载体。

6. 上位机软件与生态:墨水屏改图工具与 SignalRGB 插件

3.Software提供与键盘交互的电脑端软件:

  • 修改墨水屏图片工具(修改墨水屏图片.zip):视频中演示的傻瓜化改图上位机,用于向 Dynamic 组件的电子墨水屏写入自定义图片;
  • SignalRGB 插件(HelloWord_plugin.js):对接 SignalRGB 灯效软件的插件。从源码可见其关键参数:VendorId = 0x1001、ProductId = 0xF103;定义了 82 个键位灯 + 3 个正面指示灯的位置矩阵(vLedPositions)与灯名列表(vLedNames),提供LightingMode(Canvas/Forced)、forcedColor、shutdownColor三个可调参数;Render()时按“每包 10 灯、共 12 页”的方式组包,包格式与上一节介绍的 33 字节上位机协议完全对应(reportid=2 +0xAC+ 页码 + RGB 数据);Shutdown()则发送0xBD命令关闭软件控制,让固件恢复内置灯效。

使用注意:键盘模块需先用Zadig(见 4.Tools/安装USB驱动/zadig-2.5.exe)安装 libusb 驱动(具体步骤可搜索教程),插件才能通过 RAW HID 通道访问键盘。

7. 二次开发指南:从改配列到扩展 APP

README 明确说明“SDK 设计与二次开发”一节待补充,但结合当前仓库源码结构,二次开发的主要切入点已经清晰:

  1. 改配列:修改 hw_keyboard.h 的keyMap各层(改配列时调整IO_NUMBER对应的 74HC165 数量与第 0 层映射表),并在 main.cpp 中调整Remap的层切换逻辑;
  2. 加灯效:替换 main.cpp 主循环中的 demo 灯效,或直接对接HID_RxCpltCallback的上位机协议(0xAC/0xBD);
  3. 扩展 Dynamic APP:在 ascii_protocol.cpp 的OnAsciiCmd中追加自定义命令帧,在上层新增 FreeRTOS 任务处理业务逻辑;
  4. 自定义力反馈:修改 knob.cpp 中各模式的 PID 参数,或新增Mode_t枚举与对应的Tick()分支;
  5. 重新构建工程:用 STM32CubeMX 打开两个.ioc文件(HelloWord-Keyboard-fw.ioc/HelloWord-Dynamic-fw.ioc)重新生成工程,编译后按 2.Firmware/_Release 中的 bin 文件格式,用 ST-Link Utility / STM32CubeProgrammer 经 SWD 口下载。

从源码结构看,键盘固件对“按键数、灯数、层数”均以编译期常量集中定义(IO_NUMBER / KEY_NUMBER / LED_NUMBER / keyMap[5][88]),模块固件则把电机、编码器、驱动、触感全部封装为可组合类,二者都为后续的图形化改键软件、模块 APP 应用商店等 SDK 规划预留了清晰的扩展接口。

项目感谢了 AutoHotkey、u8g2 显示库、Arduino-FOC 与 TrafficMonitor 等开源项目,其中 u8g2 以源码形式内嵌于 BSP/u8g2,FOC 控制思路与 Ctrl 系列开源项目一脉相承,可以作为深入阅读的对照材料。

  • 硬件开发
  • 嵌入式
  • 智能硬件
  • 固件

【免费下载链接】HelloWord-Keyboard

项目地址:https://gitcode.com/gh_mirrors/he/HelloWord-Keyboard
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 15:50:30

STM32F103+ SX1278 LoRa点对点通信最小可行代码解析

简介&#xff1a;本资源是一份专为STM32F103系列MCU优化的LoRa通信精简代码包&#xff0c;面向嵌入式初学者与项目开发者&#xff0c;聚焦LoRa点对点收发核心功能&#xff0c;剔除正点原子原版中冗余的LCD显示、按键交互等非通信模块&#xff0c;显著降低学习门槛与移植复杂度。…

作者头像 李华
网站建设 2026/10/15 15:49:15

STM32 HAL库驱动MPU6050实战:从零偏校准到姿态解算避坑指南

简介&#xff1a;这份资源面向嵌入式开发初学者与需要快速上手传感器通信的工程师&#xff0c;提供基于STM32 HAL库驱动MPU6050六轴陀螺仪与加速度计的完整工程。项目在CLion环境下开发&#xff0c;借助STM32CubeMX生成初始化代码&#xff0c;通过虚拟串口输出传感器数据&#…

作者头像 李华
网站建设 2026/10/15 15:49:08

PID控制实战:从代码解压到STM32硬件调参全链路解析

简介&#xff1a;本资源是一套面向嵌入式开发初学者与单片机工程师的PID控制算法实战代码库&#xff0c;聚焦STM32平台闭环控制场景&#xff0c;解决电机调速、温控系统、智能小车等典型应用中控制器设计与调试难题。压缩包共394个文件&#xff0c;以99个C源文件和102个头文件&…

作者头像 李华