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按键
现在的(精英)手柄一般都有背键,好像能自己设置。后面再研究一下是咋整的。
得下载来学习学习,感谢分享! 矩阵键盘可以支持组合按键吗?比如A+B,游戏里常常用到。
页:
[1]