STM32制作单手鼠标键盘
单手操作电脑时,真正打断节奏的往往是手掌在键盘和鼠标之间来回移动。输入几个字、移动指针、点击按钮,再把手放回键位,每次切换都要重新寻找位置。把轨迹球、滚轮和鼠标按键放进键盘,首先解决的是这个动作链路。
这款单手键盘采用 STM32G431CBU6,提供左手小型、左手大型和右手大型三个版本。主体使用 57 颗键轴,字符区之外还集成鼠标与方向控制。它的工程价值在于将不同类型的输入统一送入 QMK,再经 USB 交给电脑。按键是离散状态,轨迹球是位移增量,滚轮是带方向的脉冲,三者需要各自采集,最后在报告层协同。
三条输入路径汇入同一个 USB 设备
字符键与鼠标按键通过矩阵采集,轨迹球通过 SPI1 读取,滚轮编码器使用独立的两根信号线。这样拆分后,键位多少、指针如何移动以及滚轮如何转动,分别由矩阵、指点设备驱动和编码器模块处理,互相之间不需要借用对方的扫描时序。
大键盘把 Type-C、滚轮、轨迹球和方向键做成独立小板,主板上的 CON1 至 CON4 用于区分模块。小型版本的 Type-C 则位于控制板上。模块化既方便适应外壳,也让故障定位更直接。字符输入正常而指针不动时,应优先检查轨迹球支路,而不是从整个键盘矩阵重新查起。
供电同样要分清边界。控制板中能看到 ME6211C33M5G-N 稳压器,将 VBUS 转为 3.3V,供主控与相关电路使用。轨迹球小板的接口标注也是 3.3V。USB 上的 5V 和器件逻辑电平不能混为一谈,排线插错位置可能同时影响供电和通信。Type-C 的两路 CC 各有 5.1kΩ 下拉,使接口以受电端身份被识别,这也是兼容 C-C 连接需要具备的硬件条件。
用 20 根扫描线管理分散的按键
共用配置给出了 6 行、14 列的矩阵,使用 20 根 GPIO 覆盖最多 84 个坐标。实际布局并没有填满这些位置。以小型左手版本为例,默认布局列出 64 个有效坐标,其中还包括鼠标按键、滚轮按压和方向键,不能把矩阵容量直接当成键轴数量。
"diode_direction":"ROW2COL","matrix_pins":{"cols":["A0","A1","A2","C4","B0","B1","B2","B7","B5","B3","B10","C11","C10","A15"],"rows":["B12","B15","C6","B13","B14","A8"]}这里的ROW2COL描述二极管允许电流从行流向列,不代表固件逐行拉低。QMK 对这种方向的处理是逐列选通,将当前列拉低,同时读取带上拉的行输入。某个按键闭合后,对应行经开关与二极管连到低电平列,行输入由高变低,软件据此置位该坐标。
逐键串联的二极管阻断了不希望出现的反向路径,避免多个按键同时闭合时,电流绕经其他开关形成虚假的按键位置。机械触点本身仍会抖动,所以电气隔离之后还需要消抖,不能把二极管和消抖看成同一件事。
物理位置与发送给电脑的键值也相互独立。布局文件决定一个键对应哪个矩阵坐标,键映射再决定这个坐标发送字符还是鼠标按钮。例如默认映射中的QK_MOUSE_BUTTON_1与普通字符键一样来自矩阵,但最终进入鼠标按钮报告。调整外壳位置时应先保持坐标、电路与键映射一致,不能只改键帽上的文字。
轨迹球先变成位移,再变成光标
轨迹球小板采用 ADNS-9800 光学传感器。球面相对传感器运动后,器件输出沿两个方向的相对位移,主控不需要计算球的绝对角度。球座则负责维持稳定的球面距离与转动阻力,机械结构会直接影响位移采集是否连续。
固件中的接口定义与硬件网名对应如下。片选决定本次访问由哪个外设响应,SCK 提供传输节拍,MOSI 发送命令与配置,MISO 返回状态和位移。MOTION 是运动提示线,不承载坐标数据。
#defineSPI_DRIVERSPID1#defineSPI_SCK_PINA5#defineSPI_MISO_PINA6#defineSPI_MOSI_PINA7#definePOINTING_DEVICE_CS_PINA4#definePOINTING_DEVICE_MOTION_PINA3#definePOINTING_DEVICE_TASK_THROTTLE_MS1#definePOINTING_DEVICE_INVERT_X1这段配置把任务节流设为 1ms,但它只是固件调度参数,不能据此宣称整机端到端延迟为 1ms。X 轴反向则用于适配传感器与球体的实际安装方向。如果只在电脑里调鼠标速度,无法修正传感器坐标轴接反造成的方向错误。
初始化阶段会从用户配置区取出灵敏度,初始化传感器,再写入 CPI。
voidpointing_device_init_kb(void){wait_ms(10);user_config.TrackballDPI=eeconfig_read_user();wait_ms(10);adns9800_init();wait_ms(10);pointing_device_set_cpi(user_config.TrackballDPI);}CPI 表示每英寸对应的计数,决定相同球面位移产生多少计数。项目把默认值设为 3000,用户调节函数按 1000 递增或递减,限制在 1000 至 8000。这里改变的是传感器灵敏度,电脑端的指针加速仍会进一步影响屏幕上的移动距离。
一个容易忽略的细节是,代码中定义了DPI_UP和DPI_DOWN,并写好了按下事件的处理,但所检查的小型版本默认键位表没有把这两个自定义键码放到可按的位置。因此,存在调节函数不等于默认布局已经提供调节快捷键。需要这一功能时,还要补上明确的键位或功能层。
连续读取位移时,字节顺序不能反
ADNS-9800 驱动通过 Motion Burst 连续取得运动状态与位移。命令发出后,程序等待规定的间隔,再读取状态。如果运动标志有效,先跳过观察字节,然后按低字节、高字节的顺序读取 X、Y 增量。
uint8_tdelta_x_l=spi_read();uint8_tdelta_x_h=spi_read();uint8_tdelta_y_l=spi_read();uint8_tdelta_y_h=spi_read();report.x=convertDeltaToInt(delta_x_h,delta_x_l);report.y=convertDeltaToInt(delta_y_h,delta_y_l);低字节先从总线上到达,组装数值时高字节却要放在高 8 位,两者并不矛盾。驱动随后将这组补码解释为有符号增量,否则反方向移动就可能被错误当作很大的正数。数据再经过 HID 位移范围约束,形成鼠标报告,由 USB 发送给主机。
因此,排查轨迹球故障应沿着数据流推进。先检查 3.3V 与地,再确认片选、时钟和收发线,之后查看运动状态与增量是否变化,最后检查方向变换和主机报告。若 SPI 没有正确返回数据,反复修改 CPI 无法解决问题;若增量已经正常而光标方向错误,则应检查坐标方向配置。
这里还有一个软件边界。传感器驱动允许通过弱函数提供 SROM 数据,默认弱实现返回长度为零,初始化会走无外部 SROM 上传分支。修改驱动或更换传感器时,需要连同初始化条件一起核对,不能只迁移四根 SPI 线与一个驱动名称。
滚轮转动与按下走不同的链路
滚轮的 A、B 两相连接 PA9 和 PA10,两路信号相位的先后关系用来判断方向。共用配置中的ENCODER_RESOLUTION为 2,决定累计多少编码状态变化才产生一次逻辑动作。分辨率与实际编码器不匹配时,就可能出现一格触发次数不合适或动作不连贯的问题。
constuint16_tPROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]={[0]={ENCODER_CCW_CW(MS_WHLU,MS_WHLD)}};默认映射将两个方向转换为滚轮上翻与下翻。滚轮按压却是另一只机械开关,经二极管进入按键矩阵,并映射为鼠标中键。编码器旋转与开关按下共用一个外观部件,却属于不同采集通道,所以“能滚动但不能中键点击”时,应检查开关、二极管和矩阵连接,而不是只盯着 A、B 两相信号。
先验证裸板,再把手感装进外壳
大型版本的键盘板采用 1.6mm 四层 FR-4,小型版本采用 1.6mm 双层板。两种规格的轴体与结构不同,左右大型版本也并非完全镜像,采购与装配时需要让 PCB、固件和模型对应到同一版本。
排线使用 0.5mm 间距、8P 接口,装配要求是反向排线。判断连接方向时,既要看 CON 标识,也要看连接器接触面,不能只凭排线颜色。首次烧录可按住控制板背面标有 B 的按钮再接入 USB,进入 STM32 DFU;已有相应固件后,才可使用按住 ESC 上电的更新路径。
比较稳妥的装配顺序是先连接模块,只装 3 至 5 颗轴体、滚轮和轨迹球,完成基本功能检查,再装外壳、填充棉与其余键帽。这样能把电路问题与机械干涉分开定位。
| 观察到的现象 | 优先检查的位置 | 判断依据 |
|---|---|---|
| USB 无法识别 | 数据线、供电、D+ 与 D−、烧录状态 | 设备尚未进入正常枚举阶段 |
| 整行或整列按键失效 | 对应扫描 GPIO、连接器与走线 | 多个异常键共享同一根扫描线 |
| 个别按键不稳定 | 轴体接点、焊点与二极管 | 局部触点问题常先于整体扫描问题 |
| 指针方向相反 | 传感器安装方向与轴向配置 | 有位移说明采集链路已部分工作 |
| 滚轮正常而中键无效 | 按压开关与矩阵通道 | 旋转与按下由不同电路采集 |
轨迹球采用直径 25mm 的 PTFE 球体,球座中安装 6 颗直径 2mm 的 PTFE 支撑球。球体是否受力均匀、打印件是否有毛刺,都应在锁紧外壳前检查。电子部分能够稳定识别输入,是装配的前提;机械部分让输入动作轻、稳、连续,才决定这套单手布局能否长期使用。
把键盘与鼠标整合到一只手的活动范围内,需要同时处理矩阵扫描、光学位移、编码器方向和机械支撑。STM32G431 将这些输入分路采集,QMK 再把它们组织成电脑能识别的报告。沿着供电、信号、固件与结构逐层核对,既能理解这款键盘为什么这样设计,也能更有把握地修改键位、替换模块与调整手感。