打印
[应用相关]

并口PS手柄改USB接口

[复制链接]
4615|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
         这几天学习用STM32 HAL库,发现用HID USB 实在是太方便了,刚好手头有一副并口PS手柄,于是试着改成USB手柄。
采取STM32读取PS手柄数据,再通过USB发送给PC的方案。

首先拆开PS手柄,PS手柄共有7根线,和STM连接方式如下:
    手柄端:                                   STM32端:
红:VCC 3-5V
黑:GND
黄:ATT ------------------------------------ PB.14(选择线,由单片机输出)
橙:COMMAND-----------------------------PD.10(命令线,由单片机输出)
棕:DATA----------------------------------- PD.8(数据线,由手柄输出)
蓝:CLOCK ---------------------------------PD.12(时钟线,由单片机输出)
绿:ACK (这根线可以不用连接)
单片机引脚:PB.14  PD.10  PD.12设置成推挽输出, PD.8 设置为上拉输入

打开STM32CubeMx软件,配置好引脚和时钟,USB_DEVICE里面选着Human Interface Device Class(HID),其他的全部默认即可。

关键部位修改
usbd_hid.c文件里的报告描述符:
__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE]  __ALIGN_END =
{
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x10,                    //     USAGE_MAXIMUM (Button 16)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x10,                    //     REPORT_COUNT (16)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x32,                    //     USAGE (Z)
    0x09, 0x33,                    //     USAGE (Rx)
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x04,                    //     REPORT_COUNT (4)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //     END_COLLECTION
    0xc0                           // END_COLLECTION
};


usbd_hid.h文件里面:
#define HID_MOUSE_REPORT_DESC_SIZE    46 //这个值根据报告描述符修改


PS手柄读取:
uint8_t res[5];                                        //保存手柄返回值
uint8_t PSInOut(uint8_t data);                //手柄的命令发送,数据接收
uint8_t HIDBuffer[6];                            //USB的数据缓冲区



//PS手柄读写函数,data参数为0表示只读数据
uint8_t PSInOut(uint8_t data)
{
     volatile uint8_t res =0;//保存读取的一个字节
     volatile uint8_t j = 1;
     volatile uint8_t temp = data;
   
    //循环读写一个字节
     for(int i=0;i<8;i++)
     {         
            HAL_GPIO_WritePin(CLOCK_GPIO_Port,CLOCK_Pin,GPIO_PIN_RESET);//CLK = 0;

            HAL_Delay(1);
            if(temp !=0)
            {
                 if(data&0X01)
                    HAL_GPIO_WritePin(COMMAND_GPIO_Port,COMMAND_Pin,GPIO_PIN_SET);//CMND = 1;
                 else
                    HAL_GPIO_WritePin(COMMAND_GPIO_Port,COMMAND_Pin,GPIO_PIN_RESET);//CMND = 0;
                 data = data >>1;        
            }        
            if(HAL_GPIO_ReadPin(DATA_GPIO_Port,DATA_Pin)==GPIO_PIN_SET)//DATA == 1
                res = res +j;
            
            j = j<<1;
            HAL_Delay(1);
            
            HAL_GPIO_WritePin(CLOCK_GPIO_Port,CLOCK_Pin,GPIO_PIN_SET);//CLK = 1;
            
            HAL_Delay(2);        
     }
     return res;
}





int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        HAL_GPIO_WritePin(ATT_GPIO_Port,ATT_Pin,GPIO_PIN_RESET);//ATT = 0;
        
        res[0]=PSInOut(0x01);//开始
        res[1]=PSInOut(0x42);//请求数据,数字手柄返回0X41
        
        //参数0,表示只接收PS的数据
        res[2]=PSInOut(0);//返回值0X5A
        res[3]=PSInOut(0);//BIT7--BIT0(LEFT,DOWN,RIGHT,UP,START,,,SELECT)
        res[4]=PSInOut(0);//BIT7--BIT0(□,X,○,△,R1,L1,R2,L2)
        
        HAL_GPIO_WritePin(ATT_GPIO_Port,ATT_Pin,GPIO_PIN_SET);//ATT = 1;
        
        //将按键值转换到usb发送缓冲区
        //USB缓冲器低2字节为16个按键,第3个和第4个为X,Y坐标
        HIDBuffer[0] = res[4];
        HIDBuffer[1] = res[3]|0xF6;
        
        //将十字按键转换成X,Y坐标
        uint8_t temp = res[3] & 0xF0;
        switch(temp)
        {
            case 0xF0:
                HIDBuffer[2]=0;
                HIDBuffer[3]=0;
                break;
            case 0xe0://上
                HIDBuffer[3] = 0x81;
                break;
            case 0xb0://下
                HIDBuffer[3] = 0x7F;
                break;
            case 0x70://左
                HIDBuffer[2] = 0x81;
                break;
         case 0xd0://右
                HIDBuffer[2] = 0x7F;
                break;
            default:
                break;
        }        
        //向PC发送数据   
        USBD_HID_SendReport(&hUsbDeviceFS,HIDBuffer,6);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}


QQ截图20181024213045.png (25.79 KB )

PS手柄

PS手柄

GamePad.zip

556.46 KB

沙发
yiy| | 2018-10-25 15:13 | 只看该作者
这就浪费了吧,有专用的转换芯片

使用特权

评论回复
板凳
不爱说话| | 2018-10-29 11:18 | 只看该作者
多年前用51单片机+汇编读取过并口PS手柄:)

使用特权

评论回复
地板
八层楼| | 2018-11-6 12:10 | 只看该作者
现在很少有用并口的了吧

使用特权

评论回复
5
观海| | 2018-11-6 12:47 | 只看该作者
自己弄着玩 挺有意思的

使用特权

评论回复
6
robertwang126| | 2023-3-4 10:16 | 只看该作者
#define HID_MOUSE_REPORT_DESC_SIZE    46 //这个值根据报告描述符修改,这句话什么意思,这个值要根据自己设备的值 自己修改吗

使用特权

评论回复
7
Stahan| | 2023-3-5 20:00 | 只看该作者
有专用的转换芯片吧

使用特权

评论回复
评论
robertwang126 2023-3-6 09:58 回复TA
想试试他这个,不知道他用的stm32的那个型号芯片,自动动手做个,不想去买成品 
8
robertwang126| | 2023-3-6 10:09 | 只看该作者
这个用stm32f103c8t6行吗

使用特权

评论回复
9
liliang9554| | 2023-8-7 19:23 | 只看该作者
浪费了吧,有专用的转换芯片

使用特权

评论回复
10
午夜粪车| | 2023-8-7 19:26 | 只看该作者
多年前用51单片机+汇编读取过并口PS手柄:)

使用特权

评论回复
11
zhaoxqi| | 2023-8-7 19:27 | 只看该作者
现在很少有用并口的了吧

使用特权

评论回复
12
gongche| | 2023-8-7 19:29 | 只看该作者
自己弄着玩 挺有意思的

使用特权

评论回复
13
huwr| | 2023-8-7 19:30 | 只看该作者
#define HID_MOUSE_REPORT_DESC_SIZE    46 //这个值根据报告描述符修改,这句话什么意思,这个值要根据自己设备的值 自己修改吗

使用特权

评论回复
14
huanghuac| | 2023-8-7 19:37 | 只看该作者
有专用的转换芯片吧

使用特权

评论回复
15
happy_10| | 2023-8-7 19:40 | 只看该作者
想试试他这个,不知道他用的stm32的那个型号芯片,自动动手做个,不想去买成品

使用特权

评论回复
16
bqyj| | 2023-8-7 19:42 | 只看该作者
这个用stm32f103c8t6行吗

使用特权

评论回复
17
田舍郎| | 2023-8-7 22:58 | 只看该作者
不错的实践

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

103

帖子

0

粉丝