找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3112

积分

1

好友

420

主题
发表于 昨天 05:59 | 查看: 1| 回复: 0

项目概述

1.1 实现功能

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

  • 16 个数字按钮: 通过 4x4 矩阵键盘实现 14 个按钮 + 2 个摇杆按键
  • 双摇杆输入: 左右两个模拟摇杆,各提供 X/Y 轴数据
  • USB HID 协议: 标准 HID Gamepad 设备,即插即用,无需驱动
  • 实时响应: 10ms 扫描间隔,低延迟输入

1.2 技术特点

项目技术规格参数表

RT-Thread使用情况概述

2.1 内核配置

#define RT_THREAD_PRIORITY_MAX  32      // 32 级优先级
#define RT_TICK_PER_SECOND      1000    // 1ms 系统节拍
#define RT_USING_TIMER_SOFT             // 软件定时器
#define RT_USING_SEMAPHORE              // 信号量
#define RT_USING_MUTEX                  // 互斥锁
#define RT_USING_MAILBOX                // 邮箱

2.2 使用的组件

RT-Thread组件与用途对应表

2.3 线程设计

游戏手柄项目线程信息表

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.1 系统框图

┌─────────────────────────────────────────────────────────────┐
│                      FRDM-MCXA156                           │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐ │
│  │  4x4 矩阵   │  │  双摇杆模块  │  │     USB Device      │ │
│  │   键盘      │  │  (带按键)    │  │    (Full Speed)     │ │
│  └──────┬──────┘  └──────┬──────┘  └──────────┬──────────┘ │
│         │                │                     │           │
│   GPIO P2/P3       ADC0 CH0/1/8/13          USB0           │
│         │                │                     │           │
│  ┌──────┴────────────────┴─────────────────────┴──────────┐│
│  │                  MCXA156 MCU                           ││
│  │              (Cortex-M33 @ 96MHz)                      ││
│  └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘

游戏手柄硬件连接示意图

3.2 引脚分配

3.2.1 矩阵键盘 (4x4)

矩阵键盘引脚配置表

3.2.2 摇杆 ADC

摇杆ADC通道配置表

3.2.3 摇杆按键

摇杆按键GPIO配置表

软件框架说明

4.1 软件框架

┌─────────────────────────────────────────────────────────────┐
│                  应用层 (Application)                       │
│  ┌─────────────────────────────────────────────────────────┐│
│  │                   gamepad_app.c                         ││
│  │         (整合输入设备,映射到 USB HID 报告)              ││
│  └─────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────┤
│                  功能层 (Function)                          │
│  ┌───────────────┐  ┌───────────────┐  ┌─────────────────┐ │
│  │  key_app.c    │  │ joystick_app.c│  │   usb_app.c     │ │
│  │  (矩阵键盘)   │  │   (双摇杆)    │  │  (USB HID)      │ │
│  └───────────────┘  └───────────────┘  └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│                  驱动层 (Driver)                            │
│  ┌───────────────┐  ┌───────────────┐  ┌─────────────────┐ │
│  │   drv_pin.c   │  │   drv_adc.c   │  │   CherryUSB     │ │
│  │   (GPIO)      │  │   (ADC)       │  │   (USB Stack)   │ │
│  └───────────────┘  └───────────────┘  └─────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│                  RT-Thread 内核                             │
│         (线程调度、IPC、设备框架、自动初始化)                │
├─────────────────────────────────────────────────────────────┤
│                  硬件抽象层 (HAL)                           │
│                 NXP MCX SDK / 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()
                                                                   │
                                                                   ▼
                                                                USB Host(PC)

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

软件模块说明

5.1 key_app 模块(矩阵键盘)

文件: applications/key_app.c, applications/key_app.h
功能: 4x4 矩阵键盘扫描
核心函数:

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

扫描原理:

  1. 逐列输出低电平
  2. 读取所有行引脚状态
  3. 检测到低电平表示该交叉点按键被按下

5.2 joystick_app 模块(摇杆)

文件: applications/joystick_app.c, applications/joystick_app.h
功能: 双摇杆 ADC 读取与按键检测
数据结构:

typedef struct {
    int16_t x;      // X轴: -32768 ~ 32767
    int16_t y;      // Y轴: -32768 ~ 32767
    bool btn;       // 按键: true=按下
} joystick_data_t;

核心函数:

rt_err_t joystick_left_read(joystick_data_t *data);
rt_err_t joystick_right_read(joystick_data_t *data);

5.3 usb_app 模块(USB HID)

文件: applications/usb_app.c, applications/usb_app.h
功能: USB HID 游戏手柄设备实现
HID 报告结构 (9 字节):

typedef struct __attribute__((packed)) {
    uint16_t buttons;      // 16 个按钮
    int8_t left_x;         // 左摇杆 X (-127 ~ 127)
    int8_t left_y;         // 左摇杆 Y
    int8_t right_x;        // 右摇杆 X
    int8_t right_y;        // 右摇杆 Y
    uint8_t left_trigger;  // 左扳机 (0-255)
    uint8_t right_trigger; // 右扳机 (0-255)
    uint8_t hat;           // 方向键 (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 忙碌时保留报告,下次重试

按键映射:

矩阵按键与HID按钮映射表

5.5 drv_adc 模块(ADC 驱动)

文件: Libraries/drivers/drv_adc.c
功能: LPADC 驱动,支持多通道 ADC 读取
关键修改:

  1. 修复了多通道初始化覆盖问题
  2. 添加了超时保护,防止系统死锁
  3. 优化了命令槽分配(4 个通道使用 4 个独立命令槽)

演示效果

6.1 启动日志

KEY OK
joystick: init OK
[USB] Initializing HID Gamepad...
[USB] HID Gamepad initialized successfully
[USB] VID:0x045E PID: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(游戏控制器)可测试所有按钮和摇杆

Windows游戏控制器测试界面

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

gamepad-tester.com 在线测试界面动图

USB HID数据实时监测界面动图

6.3 功能演示

  • 16 个按钮正常响应
  • 左右摇杆 X/Y 轴正常

摇杆轴数据可视化演示动图

游戏控制器校准页面动图

  • 摇杆按键正常

摇杆按键触发数据动图

  • 低延迟响应

低延迟数据流监控动图

代码地址

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 驱动(已修改)

总结

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

  1. 模块化设计: 硬件层、功能层、应用层分离,易于维护
  2. 实时性好: 基于 RT-Thread 实时内核,10ms 扫描周期
  3. 兼容性强: 标准 HID 协议,Windows/Linux/macOS 免驱
  4. 可扩展: 可方便添加震动反馈、LED 指示等功能

这个项目完整展示了如何利用 RT-Thread 的设备驱动框架和 CherryUSB 协议栈,在 NXP MCXA156 这样的 Cortex-M33 平台上快速构建一个功能完善的 USB HID 外设。其清晰的架构和代码实现,也为其他嵌入式开发者提供了一个很好的参考案例。如果你对更多嵌入式系统开发技巧感兴趣,欢迎到 云栈社区 交流探讨。




上一篇:Claude Sonnet 5 模型代号“Fennec”泄露,编程能力提升成本反降
下一篇:Oracle 11g/12c 系统表空间告急?审计表AUD$空间清理与迁移实战
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-5 00:46 , Processed in 0.359929 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表