STM32F429连接USB飞行摇杆 (二) 摇杆协议

本文介绍摇杆的协议和示例工程源码下载地址。

摇杆功能说明:

摇杆的数据长度是8个字节。这个值是从描述符中读取到的。

下图是功能与字节的对应关系:

用结构体描述的协议

    struct {
        //byte0
        uint8_t asix_x;  //左右翻滚
        //byte1
        uint8_t asix_y;  // 上俯 下俯
        //byte2
        uint8_t : 8;  //保留
        //byte3
        uint8_t power;  // 加速 减速
        //byte4
        uint8_t asix_rz: 8;   //扭动,平移
        //byte5
        uint8_t hat_pov : 4;  //8方向 苦力帽 0-7
        uint8_t key1 : 1;
        uint8_t key2 : 1;
        uint8_t key3 : 1;
        uint8_t key4 : 1;
        //byte6
        uint8_t key5 : 1;
        uint8_t key6 : 1;
        uint8_t key7 : 1;
        uint8_t key8 : 1;
        uint8_t key9 : 1;
        uint8_t key10 : 1;
        uint8_t key11 : 1;
        uint8_t key12 : 1;
        //byte7
        uint8_t : 8;  //保留
    }

读取摇杆数据,解析数据,执行回调:

static USBH_StatusTypeDef USBH_HID_JoyStickDecode(USBH_HandleTypeDef *phost)
{
  HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;

  if (HID_Handle->length == 0U)
  {
    return USBH_FAIL;
  }

    //读取USB摇杆数据
  if (USBH_HID_FifoRead(&HID_Handle->fifo, &joystick_report_data, HID_Handle->length) ==  HID_Handle->length)
  {
      //解析USB摇杆数据
      joystick_info.new_joystick.full = joystick_report_data;

      if(joystick_info.old_joystick.full ==0)
      {
          joystick_info.old_joystick.full = joystick_info.new_joystick.full;
      }
      else
      {
        if(joystick_info.old_joystick.full != joystick_info.new_joystick.full)
        {
            //判断 X,Y,Z
            if(joystick_info.old_joystick.data.asix_x != joystick_info.new_joystick.data.asix_x)
            {
                if(abs(joystick_info.old_joystick.data.asix_x - joystick_info.new_joystick.data.asix_x) > 1)
                {
                    on_JoyStick_X_Moved(&joystick_info);
                    joystick_info.old_joystick.data.asix_x = joystick_info.new_joystick.data.asix_x;
                }
            }
            if(joystick_info.old_joystick.data.asix_y != joystick_info.new_joystick.data.asix_y)
            {
                if(abs(joystick_info.old_joystick.data.asix_y - joystick_info.new_joystick.data.asix_y) > 1)
                {
                    on_JoyStick_Y_Moved(&joystick_info);
                    joystick_info.old_joystick.data.asix_y = joystick_info.new_joystick.data.asix_y;
                }
            }
            if(joystick_info.old_joystick.data.asix_rz != joystick_info.new_joystick.data.asix_rz)
            {
                if(abs(joystick_info.old_joystick.data.asix_rz - joystick_info.new_joystick.data.asix_rz) > 2)
                {
                    on_JoyStick_RZ_Moved(&joystick_info);
                    joystick_info.old_joystick.data.asix_rz = joystick_info.new_joystick.data.asix_rz;
                }
            }

            //power 加减速
            if(joystick_info.old_joystick.data.power != joystick_info.new_joystick.data.power)
            {
                if(abs(joystick_info.old_joystick.data.power - joystick_info.new_joystick.data.power) > 3)
                {
                    on_JoyStick_Power_Changed(&joystick_info);
                    joystick_info.old_joystick.data.power = joystick_info.new_joystick.data.power;
                }
            }

            //苦力帽方向
            if(joystick_info.old_joystick.data.hat_pov != joystick_info.new_joystick.data.hat_pov)
            {
                on_JoyStick_POV_Changed(&joystick_info);
                joystick_info.old_joystick.data.hat_pov = joystick_info.new_joystick.data.hat_pov;
            }

            //按键
            joystick_info.old_keys =  joystick_info.old_joystick.data32[1] & 0x00FFF000;
            joystick_info.new_keys =  joystick_info.new_joystick.data32[1] & 0x00FFF000;
            if(joystick_info.old_keys != joystick_info.new_keys)
            {
                on_JoyStick_Key_Changed(&joystick_info);
                joystick_info.old_joystick.data32[1] = joystick_info.old_joystick.data32[1] & (0xFF000FFF);
                joystick_info.old_joystick.data32[1] = joystick_info.old_joystick.data32[1] | (joystick_info.new_keys);
            }
        }
      }

    return USBH_OK;
  }
  return   USBH_FAIL;
}

回调函数使用了__weak 修饰符,方便重写。

重写方法的示例user_it.c文件

#include <user_it.h>
#include <stdio.h>
#include "main.h"
#include "joystickprotocol.h"

struct UsbControler usb;

void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
{
    if(Appli_state == APPLICATION_READY)
    {
        USBH_HID_GetJoyStickInfo(&hUsbHostFS);
    }
}

void on_JoyStick_Key1_Down(joystick_event_t * e)
{
    sprintf(usb.uartbuffer,"key1 down  ");
    HAL_UART_Transmit(&huart2, (unsigned char *)usb.uartbuffer, strlen(usb.uartbuffer), 1000);
}

void on_JoyStick_Key1_Up(joystick_event_t * e)
{
    sprintf(usb.uartbuffer,"key1 up  ");
    HAL_UART_Transmit(&huart2, (unsigned char *)usb.uartbuffer, strlen(usb.uartbuffer), 1000);
}

void on_JoyStick_Key2_Down(joystick_event_t * e)
{
    sprintf(usb.uartbuffer,"key2 down  ");
    HAL_UART_Transmit(&huart2, (unsigned char *)usb.uartbuffer, strlen(usb.uartbuffer), 1000);
}

void on_JoyStick_Key2_Up(joystick_event_t * e)
{
    sprintf(usb.uartbuffer,"key2 up  ");
    HAL_UART_Transmit(&huart2, (unsigned char *)usb.uartbuffer, strlen(usb.uartbuffer), 1000);
}

void on_JoyStick_Power_Changed(joystick_event_t * e)
{
    sprintf(usb.uartbuffer," power = %d  ", e->new_joystick.data.power);
    HAL_UART_Transmit(&huart2, (unsigned char *)usb.uartbuffer, strlen(usb.uartbuffer), 1000);
}

完整代码请下载工程文件源码。

工程使用CubeIDE 1.11创建,使用了FreeRTOS。

下载地址:

单片机STM32F429连接USB飞行摇杆示例工程-单片机文档类资源-CSDN文库

STM32F429连接USB飞行摇杆 (一) 连接摇杆

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STM32F103C8 (Source Code) Serial(UART) to USB HID Keyboard Mouse Joystick 串口 转 USB键盘;鼠标;手柄 源码 (1) 使用Composite Device 组合(复合)设备 (1.1) 1个Device -> 1个 Configuation -> 3个Interfance (Keyboard & Mouse & Joystick) (1.2) Keyboard Interfance -> HID (boot mode) -> 2个Endpoint(IN_0x81 & OUT_0x01) -> KeyboardReportDescriptor(不使用Report ID) (1.3) Mouse Interfance -> HID (boot mode) -> 1个Endpoint(IN_0x82) -> MouseReportDescriptor(不使用Report ID) (1.4) Joystick Interfance -> HID -> 1个Endpoint(IN_0x83) -> JoyStickReportDescriptor (1.5) 使用HID boot模式, 不使用Report ID, 以便兼容在 计算器设定BIOS模式 中的操作 (1.6) 支持反馈Keyboard_LED灯号: All Off; Num Lock; Caps Lock; Scroll Lock; Compose; Kana (2) 串口接收 命令 (2.1) UART协议: 115200, n, 8, 1 (2.2) 1帧发送字符串格式, 以 '{'开始, '}'结束 ','分隔 共9个10进制数字 例如: {1,2,3,4,5,6,7,8,9} (2.3) 第1位 区分 Keyboard(128) 或是 Mouse(64) 或是 Joystick(32) 命令 例如: {32, 0,0,0,0,0,0,0,0} --- 发送Joystick命令 {64, 0,0,0,0,0,0,0,0} --- 发送Mouse命令 {128,0,0,0,0,0,0,0,0} --- 发送Keyboard命令 (3) 发送Keyboard键盘命令时 : 第2~9位 分别如下 (3.1) 第2位 : Modify_Key(修饰键) Key_Release = 0x00, Left_Control = 0x01, Left_Shift = 0x02, Left_Alt = 0x04, Left_GUI = 0x08, Right_Control = 0x10, Right_Shift = 0x20, Right_Alt = 0x40, Right_GUI = 0x80, 例如: {128, 8,0,0,0,0,0,0,0} --- 发送 Win_Key键 {128, 128,0,0,0,0,0,0,0} --- 发送 WinApp_Key键 {128, 32,0,0,0,0,0,0,0} --- 发送 右Shift键 (3.2) 第3位 : 保留,不使用,一律填0 (3.3) 第4~9位 : 可以同时发送6个Keyboard按键 例如: {128, 0,0,4,5,6,7,8,9} --- 发送 'abcdef'键 {128, 2,0,4,5,6,7,8,9} --- 按住 左Shift 发送 'abcdef'键 => 'ABCDEF' {128, 0,0,0,5,0,7,0,9} --- 发送 'bdf'键 (0表示 无按键) 按键码 可参阅: (HID Usage ID) http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf https://www.hiemalis.org/~keiji/PC/scancode-translate.pdf https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2 http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (4) 发送Mouse鼠标命令时 : 第8~9位 分别如下 (4.1) 第2位 : 鼠标按钮(左,中,右)占3bits Button_Release = 0x00, Left_Button = 0x01, Right_Button = 0x02, Mid_Button = 0x04, 例如: {64, 1,0,0,0,0,0,0,0} --- 点击 左键 {64, 2,0,0,0,0,0,0,0} --- 点击 右键 {64, 4,0,0,0,0,0,0,0} --- 点击 中键 (4.2) 第3~5位 : 移动(X,Y), 滚轮(Wheel) X: -127~127:左右移动鼠标 Y: -127~127:上下移动鼠标 Wheel: -127~127:上下转动滚轮 例如: {64, 0,20,-10,0,0,0,0,0} --- 鼠标 右移20,上移10 {64, 0,0,0,-30,0,0,0,0} --- 滚轮-30 (4.3) 第6~9位 : 保留,不使用,一律填0 (5) 发送Joystick手柄命令时 : 第8~9位 分别如下 (5.1) 第2~4位 : 移动X,Y,Z X: -127~127:X轴左右移动手柄 Y: -127~127:Y轴上下移动手柄 Z: -127~127:Z轴转动手柄 例如: {32, -127,0,0,0,0,0,0,0} --- 移动手柄X轴到-127(最右边) {32, 0,127,0,0,0,0,0,0} --- 移动手柄Y轴到127(最下面) {32, -95,32,96,0,0,0,0,0} --- 移动手柄X,Y,Z轴到(-95,32,96) (5.2) 第5~7位 : 旋转X,Y,Z X: -127~127:X轴旋转 Y: -127~127:Y轴旋转 Z: -127~127:Z轴旋转 例如: {32, 0,0,0, 63,0,0,0,0} --- 旋转手柄X轴到63 {32, 0,0,0, 0,-32,0,0,0} --- 旋转手柄Y轴到-32 {32, 0,0,0, 0,0,127,0,0} --- 旋转手柄Z轴到127 (5.3) 第8位 : 2个 Hat_switch(方向帽) POV1, POV2 POV1_0 = 0x00, POV1_45 = 0x01, POV1_90 = 0x02, POV1_135 = 0x03, POV1_180 = 0x04, POV1_225 = 0x05, POV1_270 = 0x06, POV1_315 = 0x07, POV2_0 = 0x00, POV2_45 = 0x10, POV2_90 = 0x20, POV2_135 = 0x30, POV2_180 = 0x40, POV2_225 = 0x50, POV2_270 = 0x60, POV2_315 = 0x70, 例如: {32, 0,0,0, 0,0,0, 3,0} --- POV1到90度 {32, 0,0,0, 0,0,0, 103,0} --- POV1到135度(0x07);POV2到270度(0x60) 即(0x07+0x60=0x67=103) (5.4) 第9位 : 8个按钮(每个按钮占1bit) 例如: {32, 0,0,0, 0,0,0, 0,85} --- 按钮: (0x55=85) 1,3,5,7:ON; 2,4,6,8:OFF {32, 0,0,0, 0,0,0, 0,170} --- 按钮: (0xAA=170) 1,3,5,7:OFF; 2,4,6,8:ON

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值