本文介绍摇杆的协议和示例工程源码下载地址。
摇杆功能说明:
摇杆的数据长度是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。
下载地址: