本帖最后由 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[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff};
- BYTE PadCode_Down[12];
-
- BYTE keyPadData[20] = {0x00, 0x14,
- 0x00, // 第一组按键 R L SE ST RI LE DO UP
- 0x00, // 第二组按键 Y X B A NOP ME 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[0] = HPadCode;
- PadCode_Down[1] = LPadCode;
- PadCode_Down[2] = LTCode;
- PadCode_Down[3] = RTCode;
- PadCode_Down[4] = HLXCode;
- PadCode_Down[5] = LLXCode;
- PadCode_Down[6] = HLYCode;
- PadCode_Down[7] = LLYCode;
- PadCode_Down[8] = HRXCode;
- PadCode_Down[9] = LRXCode;
- PadCode_Down[10] = HRYCode;
- PadCode_Down[11] = LRYCode;
-
- for (i = 0; i < 12; i++) {
- keyPadData[i + 2] = PadCode_Down[i];
- }
- } else {
- if (SendCnt < 3) {
- SendCnt++;
- } else {
- SendCnt = 0;
- P6 = 0x3f;
- HPadCode = PadCode_Idle[0];
- LPadCode = PadCode_Idle[1];
- LTCode = PadCode_Idle[2];
- RTCode = PadCode_Idle[3];
- HLXCode = PadCode_Idle[4];
- LLXCode = PadCode_Idle[5];
- HLYCode = PadCode_Idle[6];
- LLYCode = PadCode_Idle[7];
- HRXCode = PadCode_Idle[8];
- LRXCode = PadCode_Idle[9];
- HRYCode = PadCode_Idle[10];
- LRYCode = PadCode_Idle[11];
-
- for (i = 0; i < 12; i++) {
- keyPadData[i + 2] = PadCode_Idle[i];
- }
- }
- }
- }
复制代码
再次修改usb_class_in(), 修改矩阵键盘相应,分别对应 A B X Y 与左轴的上下左右
注意摇杆是双字节有符号数 负方向移动需要使用补码 -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按键
现在的(精英)手柄一般都有背键,好像能自己设置。后面再研究一下是咋整的。
|