当前位置:首页 > 国际财讯 > 基于RT-Thread与MCXA156的USB HID游戏手柄设计与实现 | 技术集结

基于RT-Thread与MCXA156的USB HID游戏手柄设计与实现 | 技术集结

目录

项目概述

RT-Thread 使用情况概述

硬件框架

软件框架说明

软件模块说明

效果演示

代码地址

总结

1 项目概述

1.1 实现功能

本项目基于 NXP FRDM-MCXA156 开发板,实现了一个标准的 USB HID 游戏手柄设备,主要功能包括:

16 个数字按钮:通过 4x4 矩阵键盘实现 14 个按钮 + 2 个摇杆按键

双摇杆输入:左右两个模拟摇杆,各提供 X/Y 轴数据

USB HID 协议:标准 HID Gamepad 设备,即插即用,无需驱动

实时响应:10ms 扫描间隔,低延迟输入

1.2 技术特点

6991b262-0025-11f1-96ea-92fbcf53809c.png

2 RT-Thread使用情况概述

2.1 内核配置

#defineRT_THREAD_PRIORITY_MAX 32 // 32 级优先级#defineRT_TICK_PER_SECOND 1000 // 1ms 系统节拍#defineRT_USING_TIMER_SOFT // 软件定时器#defineRT_USING_SEMAPHORE // 信号量#defineRT_USING_MUTEX // 互斥锁#defineRT_USING_MAILBOX // 邮箱

2.2 使用的组件

2.3 线程设计

69ab95b0-0025-11f1-96ea-92fbcf53809c.png

2.4 自动初始化

项目使用 RT-Thread 自动初始化机制:

INIT_BOARD_EXPORT(rt_hw_adc_init); // ADC 驱动初始化INIT_DEVICE_EXPORT(key_init); // 矩阵键盘初始化INIT_DEVICE_EXPORT(joystick_init); // 摇杆初始化INIT_COMPONENT_EXPORT(cherryusb_init); // USB 初始化INIT_APP_EXPORT(gamepad_app_start); // 应用层启动

3 硬件框架

3.1 系统框图

┌─────────────────────────────────────────────────────────────┐│ FRDM-MCXA156 ││ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐││ │ 4x4 矩阵 │ │ 双摇杆模块 │ │ USBDevice │││ │ 键盘 │ │ (带按键) │ │ (FullSpeed) │││ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘││ │ │ │ ││ GPIOP2/P3 ADC0 CH0/1/8/13 USB0 ││ │ │ │ ││ ┌──────┴────────────────┴─────────────────────┴──────────┐││ │ MCXA156MCU │││ │ (Cortex-M33@ 96MHz) │││ └─────────────────────────────────────────────────────────┘│└─────────────────────────────────────────────────────────────┘

3.2 引脚分配

3.2.1 矩阵键盘 (4x4)

69d82206-0025-11f1-96ea-92fbcf53809c.png

3.2.2 摇杆 ADC

69ec9128-0025-11f1-96ea-92fbcf53809c.png

3.2.3 摇杆按键

69fa73ba-0025-11f1-96ea-92fbcf53809c.png

4 软件框架说明

4.1 软件框架

┌─────────────────────────────────────────────────────────────┐│ 应用层 (Application) ││ ┌─────────────────────────────────────────────────────────┐││ │ gamepad_app.c │││ │ (整合输入设备,映射到USBHID报告) │││ └─────────────────────────────────────────────────────────┘│├─────────────────────────────────────────────────────────────┤│ 功能层 (Function) ││ ┌───────────────┐ ┌───────────────┐ ┌─────────────────┐ ││ │ key_app.c │ │ joystick_app.c│ │ usb_app.c │ ││ │ (矩阵键盘) │ │ (双摇杆) │ │ (USBHID) │ ││ └───────────────┘ └───────────────┘ └─────────────────┘ │├─────────────────────────────────────────────────────────────┤│ 驱动层 (Driver) ││ ┌───────────────┐ ┌───────────────┐ ┌─────────────────┐ ││ │ drv_pin.c │ │ drv_adc.c │ │ CherryUSB │ ││ │ (GPIO) │ │ (ADC) │ │ (USBStack) │ ││ └───────────────┘ └───────────────┘ └─────────────────┘ │├─────────────────────────────────────────────────────────────┤│ RT-Thread内核 ││ (线程调度、IPC、设备框架、自动初始化) │├─────────────────────────────────────────────────────────────┤│ 硬件抽象层 (HAL) ││ NXPMCXSDK/CMSIS │└─────────────────────────────────────────────────────────────┘

4.2 数据流

矩阵键盘 ──► key_read() ──────────────────────────────────┐ │左摇杆 ADC ──► joystick_left_read() ──► apply_deadzone() ──┤ ├──► gamepad_thread右摇杆 ADC ──► joystick_right_read() ──► apply_deadzone() ──┤ │ │ ▼摇杆按键 ──► rt_pin_read() ────────────────────────────────┘ scale_axis() │ ▼ USB HID Report │ ▼ hid_gamepad_send_report() │ ▼ USBHost(PC)

严格遵守了 感知 --> 认知 --> 控制 系统设计模式

5 软件模块说明

5.1 key_app 模块(矩阵键盘)

文件:applications/key_app.c, applications/key_app.h

功能:4x4 矩阵键盘扫描

核心函数:

rt_uint8_tkey_read(void); // 返回0-15表示按键索引,0xFF 表示无按键

扫描原理:

逐列输出低电平

读取所有行引脚状态

检测到低电平表示该交叉点按键被按下

5.2 joystick_app 模块(摇杆)

文件:applications/joystick_app.c, applications/joystick_app.h

功能:双摇杆 ADC 读取与按键检测

数据结构:

typedefstruct { int16_tx; // X轴: -32768 ~ 32767 int16_ty; // Y轴: -32768 ~ 32767 boolbtn; // 按键: true=按下}joystick_data_t;

核心函数:

rt_err_tjoystick_left_read(joystick_data_t*data);rt_err_tjoystick_right_read(joystick_data_t*data);

5.3 usb_app 模块(USB HID)

文件:applications/usb_app.c, applications/usb_app.h

功能:USB HID 游戏手柄设备实现

HID 报告结构 (9 字节):

typedefstruct __attribute__((packed)) { uint16_tbuttons; // 16 个按钮 int8_tleft_x; // 左摇杆 X (-127 ~ 127) int8_tleft_y; // 左摇杆 Y int8_tright_x; // 右摇杆 X int8_tright_y; // 右摇杆 Y uint8_tleft_trigger; // 左扳机 (0-255) uint8_tright_trigger;// 右扳机 (0-255) uint8_that; // 方向键 (0-8)}usb_gamepad_report_t;

USB 描述符配置:

VID: 0x045E (Microsoft)

PID: 0x02FF (Generic Gamepad)

端点: 0x81 (IN), 中断传输

轮询间隔: 1ms

5.4 gamepad_app 模块(应用层)

文件: applications/gamepad_app.c, applications/gamepad_app.h

功能: 整合所有输入设备,映射到 USB HID 报告

核心特性:

死区处理: 消除摇杆中心位置的抖动

变化检测: 只有状态变化时才发送报告

发送重试: USB 忙碌时保留报告,下次重试

按键映射:

6a0a46f0-0025-11f1-96ea-92fbcf53809c.png

5.5 drv_adc 模块(ADC 驱动)

文件:Libraries/drivers/drv_adc.c

功能:LPADC 驱动,支持多通道 ADC 读取

关键修改:

修复了多通道初始化覆盖问题

添加了超时保护,防止系统死锁

优化了命令槽分配(4 个通道使用 4 个独立命令槽)

6 演示效果

6.1 启动日志

KEY OKjoystick:initOK[USB] Initializing HID Gamepad...[USB] HID Gamepad initialized successfully[USB] VID:0x045EPID:0x02FF[GAMEPAD] Started (interval:10ms)System Start[GAMEPAD] Thread started[USB] Device Configured - Gamepad Ready!

6.2 Windows 测试

1.设备连接后,在”设备管理器”中显示为 “USB Gamepad HID”

2.使用 joy.cpl(游戏控制器)可测试所有按钮和摇杆

6a16920c-0025-11f1-96ea-92fbcf53809c.gif

3.使用https://gamepad-tester.com/ 在线平台课测试所有按钮和摇杆

6a38910e-0025-11f1-96ea-92fbcf53809c.gif6a65e352-0025-11f1-96ea-92fbcf53809c.gif

6.3功能演示

16 个按钮正常响应

左右摇杆 X/Y 轴正常

6a7d055a-0025-11f1-96ea-92fbcf53809c.gif6a95126c-0025-11f1-96ea-92fbcf53809c.gif

摇杆按键正常

6ab0ff72-0025-11f1-96ea-92fbcf53809c.gif

低延迟响应

6ad819f4-0025-11f1-96ea-92fbcf53809c.gif

7 代码地址

Git 仓库:https://github.com/Rolmoland/Project_GamepadMi

主要文件:

applications/├── main.c # 主入口├── gamepad_app.c/h # 游戏手柄应用层├── key_app.c/h # 矩阵键盘模块├── joystick_app.c/h # 摇杆模块└── usb_app.c/h # USB HID 模块board/├── MCUX_Config/board/pin_mux.c # 引脚配置└── ports/cherryusb/ # CherryUSB 适配Libraries/drivers/└── drv_adc.c # ADC 驱动(已修改)

8 总结

本项目成功实现了基于 RT-Thread 的 USB HID 游戏手柄,具有以下特点:

模块化设计: 硬件层、功能层、应用层分离,易于维护

实时性好: 基于 RT-Thread 实时内核,10ms 扫描周期

兼容性强: 标准 HID 协议,Windows/Linux/macOS 免驱

可扩展: 可方便添加震动反馈、LED 指示等功能