原装世嘉土星SS手柄(Sega Saturn)改USB接口,实现低延时USB格斗手柄

最新第二版看这里 https://blog.csdn.net/u010438192/article/details/103528287

 

某鱼102元购入原装土星日产手柄(二手)

原装为9针接口,为了在电脑上玩热血格斗,连技用,要求速度快,所以改了USB,USB上报率达到了HID最快1000HZ

丝毫感觉不出任何延时。

准备硬件:

土星原装手柄一个

带USB的STM32核心板一块,作者选的(STM32F407VET6)

核心板作者买的下图这种:

原装世嘉土星SS手柄(Sega Saturn)改USB接口,实现低延时USB格斗手柄_第1张图片

 

5V转3.3V LDO一片 ,电解电容2片 或者直接买AMS1117-3.3模块

1.5K电阻一个

USB线一条(0.5米-1米)

硬件连接见下图

 

 

原装世嘉土星SS手柄(Sega Saturn)改USB接口,实现低延时USB格斗手柄_第2张图片

 

SS手柄接口定义如下图,作者是剪掉了插头,然后万用表找出每根线,直接焊接到STM32核心板上

https://gamesx.com/controldata/saturn.htm (ss手柄引脚定义)

原装世嘉土星SS手柄(Sega Saturn)改USB接口,实现低延时USB格斗手柄_第3张图片

 

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

 

 

 

 

 

 

你可能感兴趣的:(原装世嘉土星SS手柄(Sega Saturn)改USB接口,实现低延时USB格斗手柄)