gentleman 发表于 2023-9-5 07:58:24

USB-HID 手柄制作(二)

本帖最后由 gentleman 于 2023-9-5 09:09 编辑

测试视频链接https://www.bilibili.com/video/B ... 81d40a80ca841a25329

注意本文使用了微软360手柄的PID VID ,仅供交流学习使用。


本文使用设备描述符 等信息均来自互联网



接上回https://www.stcaimcu.com/forum.php?mod=viewthread&tid=4107




源码已上传附件

新建 pad.c /.h 文件


新建全局变量手柄键码
BYTE HPadCode = 0x00;
BYTE LPadCode = 0x00;
BYTE LTCode   = 0x00;
BYTE RTCode   = 0x00;
BYTE HLXCode= 0xf0;
BYTE LLXCode= 0xf0;
BYTE HLYCode= 0xf0;
BYTE LLYCode= 0xf0;
BYTE HRXCode= 0xf0;
BYTE LRXCode= 0xf0;
BYTE HRYCode= 0xf0;
BYTE LRYCode= 0xf0;

空闲状态键码数组 ,待发送键码数组 完整数据数组
BYTE code PadCode_Idle = {0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff};
BYTE PadCode_Down;

BYTE keyPadData = {0x00, 0x14,
                     0x00, // 第一组按键RL   SE   ST   RI   LE   DO   UP
                     0x00, // 第二组按键YX   B    A    NOPME   RB   LB
                     0x00, // LT
                     0x00, // RT
                     0x00, // LX   双字
                     0xff, // LX2
                     0x00, // LY
                     0xff, // LY2
                     0xff, // RX
                     0xff, // RX2
                     0x00, // RY
                     0x00, // RY2
                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00};判断按键按下时整理键码,与恢复空闲键码, 增加一个定时器,调用这个函数,此处省略
/// @brief 配置发送的手柄数据
/// @param
void SendPadData(void)
{
    uint i = 0;

    if (!padIdle) {
      P6 = 0x0f;

      PadCode_Down= HPadCode;
      PadCode_Down= LPadCode;
      PadCode_Down= LTCode;
      PadCode_Down= RTCode;
      PadCode_Down= HLXCode;
      PadCode_Down= LLXCode;
      PadCode_Down= HLYCode;
      PadCode_Down= LLYCode;
      PadCode_Down= HRXCode;
      PadCode_Down= LRXCode;
      PadCode_Down = HRYCode;
      PadCode_Down = LRYCode;

      for (i = 0; i < 12; i++) {
            keyPadData = PadCode_Down;
      }
    } else {
      if (SendCnt < 3) {
            SendCnt++;
      } else {
            SendCnt= 0;
            P6       = 0x3f;
            HPadCode = PadCode_Idle;
            LPadCode = PadCode_Idle;
            LTCode   = PadCode_Idle;
            RTCode   = PadCode_Idle;
            HLXCode= PadCode_Idle;
            LLXCode= PadCode_Idle;
            HLYCode= PadCode_Idle;
            LLYCode= PadCode_Idle;
            HRXCode= PadCode_Idle;
            LRXCode= PadCode_Idle;
            HRYCode= PadCode_Idle;
            LRYCode= PadCode_Idle;

            for (i = 0; i < 12; i++) {
                keyPadData = PadCode_Idle;
            }
      }
    }
}

再次修改usb_class_in(), 修改矩阵键盘相应,分别对应 ABXY与左轴的上下左右


注意摇杆是双字节有符号数负方向移动需要使用补码-65536 补码为0x8000最高位符号位为1
void usb_class_in()
{

    if (DeviceState != DEVSTATE_CONFIGURED)
      return;

    if (!UsbInBusy && fKeyOK) {

      fKeyOK = 0;

      padIdle = 0;
      switch (bKeyCode) {
            case 0xfe:
                LPadCode |= ADOWN;
                break;
            case 0xfd:
                LPadCode |= BDOWN;
                break;
            case 0xfb:
                LPadCode |= XDOWN;
                break;
            case 0xf7:
                LPadCode |= YDOWN;
                break;
            case 0xef:
                HLXCode = 0x00;
                LLXCode = 0x80;
                break;
            case 0xdf:
                HLXCode = 0xff;
                LLXCode = 0x7f;
                break;
            case 0xbf:
                HLYCode = 0x00;
                LLYCode = 0x80;
                break;
            case 0x7f:
                HLYCode = 0xff;
                LLYCode = 0x7f;
                // IAP_CONTR = 0x60;
                break;
            case 0xff:
                padIdle = 1;
                break;
      }
    }

    if (!UsbInBusy) {

      UsbInBusy = 1;

      IE2 &= ~0x80; // EUSB = 0;
      usb_write_reg(INDEX, 1);

      usb_write_fifo(FIFO1, keyPadData, 20);
      usb_write_reg(INCSR1, INIPRDY);

      IE2 |= 0x80; // EUSB = 1;
    }
}

steam 测试手柄工具   测试结果
   






后面的计划是
      购买手柄需要的摇杆(电位器),增加adc 读取摇杆值,8个矩阵按键不够,可能会使用独立按键/AD按键
      
      现在的(精英)手柄一般都有背键,好像能自己设置。后面再研究一下是咋整的。







xxkj2010 发表于 2024-6-27 08:50:21

得下载来学习学习,感谢分享!

consoleyou 发表于 2024-6-27 09:24:53

矩阵键盘可以支持组合按键吗?比如A+B,游戏里常常用到。
页: [1]
查看完整版本: USB-HID 手柄制作(二)