最新第二版看这里 https://blog.csdn.net/u010438192/article/details/103528287
某鱼102元购入原装土星日产手柄(二手)
原装为9针接口,为了在电脑上玩热血格斗,连技用,要求速度快,所以改了USB,USB上报率达到了HID最快1000HZ
丝毫感觉不出任何延时。
准备硬件:
土星原装手柄一个
带USB的STM32核心板一块,作者选的(STM32F407VET6)
核心板作者买的下图这种:
5V转3.3V LDO一片 ,电解电容2片 或者直接买AMS1117-3.3模块
1.5K电阻一个
USB线一条(0.5米-1米)
硬件连接见下图
SS手柄接口定义如下图,作者是剪掉了插头,然后万用表找出每根线,直接焊接到STM32核心板上
https://gamesx.com/controldata/saturn.htm (ss手柄引脚定义)
pin1和pin6 实际是通的,用万用表量过,这两根线其中有一根供电就OK,作者是两根都供了5V
SS手柄按键读取:
整个手柄13个按键需要4个周期读取。
第1个周期 选择线 S0 S1 分别置位 0 0 可以读取出 Z Y X R的状态
第2个周期 选择线 S0 S1 分别置位1 0 可以读取出 B C A St的状态
第3个周期 选择线 S0 S1 分别置位 0 1 可以读取出 Up Dn Lt Rt的状态
第4个周期 选择线 S0 S1 分别置位 1 1 可以读取出 L的状态
作者测试,每个周期之间必须延时50us以上才可以,要不然会时许错乱,导致读出错误的值。
代码实现如下:
uint8_t key_Z,key_Y,key_X,key_R;
uint8_t key_B,key_C,key_A,key_St;
uint8_t key_Up,key_Dn,key_Lt,key_Rt;
uint8_t key_L;
#define SCAN_DELAY_TIME 50 //us
void scan_saturn(void)
{
//s0 s1 0 0
HAL_GPIO_WritePin(GPIOD,S0_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,S1_Pin,GPIO_PIN_RESET);
delay_us(SCAN_DELAY_TIME);
key_Z = HAL_GPIO_ReadPin(GPIOD,D0_Pin);
key_Y = HAL_GPIO_ReadPin(GPIOD,D1_Pin);
key_X = HAL_GPIO_ReadPin(GPIOD,D2_Pin);
key_R = HAL_GPIO_ReadPin(GPIOD,D3_Pin);
//s0 s1 1 0
HAL_GPIO_WritePin(GPIOD,S0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,S1_Pin,GPIO_PIN_RESET);
delay_us(SCAN_DELAY_TIME);
key_B = HAL_GPIO_ReadPin(GPIOD,D0_Pin);
key_C = HAL_GPIO_ReadPin(GPIOD,D1_Pin);
key_A = HAL_GPIO_ReadPin(GPIOD,D2_Pin);
key_St = HAL_GPIO_ReadPin(GPIOD,D3_Pin);
//s0 s1 0 1
HAL_GPIO_WritePin(GPIOD,S0_Pin,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,S1_Pin,GPIO_PIN_SET);
delay_us(SCAN_DELAY_TIME);
key_Up = HAL_GPIO_ReadPin(GPIOD,D0_Pin);
key_Dn = HAL_GPIO_ReadPin(GPIOD,D1_Pin);
key_Lt = HAL_GPIO_ReadPin(GPIOD,D2_Pin);
key_Rt = HAL_GPIO_ReadPin(GPIOD,D3_Pin);
//s0 s1 1 1
HAL_GPIO_WritePin(GPIOD,S0_Pin,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,S1_Pin,GPIO_PIN_SET);
delay_us(SCAN_DELAY_TIME);
key_L = HAL_GPIO_ReadPin(GPIOD,D3_Pin);
}
HID相关代码由STM32 CUBE生成,然后改
#define HID_FS_BINTERVAL 0x00U //改为00
usbd_hid.c 枚举成游戏控制器,按键13个 (这项工作由作者的朋友帮忙完成,在这里感谢他)。
最终枚举成功后发现,把SS的数据发给USB
电脑开着机插USB 可以正常枚举成功,但是只要电脑关机后,插USB 再开机,
会出现枚举失败的情况,所以每次电脑开机必须手动插拔一下才可以。
无奈代码里做了判断,如果发现枚举失败,就把D+ 拉低一段时间以模拟手动插拔一下。
最终完美解决,和XBOX ONES PS4手柄比起来,还是喜欢用这个SS手柄玩热血格斗。
完整代码如下:
https://download.csdn.net/download/u010438192/11961661
https://github.com/liuyuf78fk/Sega-Saturn-Contro-TO-USB