需求
实习工作,老板要求用单片机读取驾驶模拟器(Joystick)返回的数据,驾驶模拟器usb输出,输出信息包括:方向盘转角、左右拨杆、按键等。

完整代码传送门
https://download.youkuaiyun.com/download/renzemingcsdn/15726059
硬件
采用正点原子探索者开发板,即插即用,硬件不需要改动。开发板做主设备,因此必须选用f4系列,f103只能做从设备,其他能做主设备的f1,没就用过,不做尝试,直接用f407zgt6。驾驶模拟器上是一个stm32单片机,商家已经擦除芯片型号,盲猜是f1系列,因为模拟驾驶器是USB从设备,只需要f1系列即可。

探索的思路
最初不知道驾驶模拟器是用什么协议,于是开始漫长的探索过程。
usb HID设备
首先,将驾驶模拟器插入windows电脑,再任务管理器中发现,多出两行,表明该设备为USB HID设备。USB HID是Human Interface Device的缩写,由其名称可以了解HID设备是直接与人交互的设备,例如键盘、鼠标与游戏杆等。通过window的系统调用,可以接收到模拟量和数字量。协议讲解 在这里。
使用Windows读取数据程序如下,也可以参考这里。
#include<stdio.h>
#include <iostream>
#include<stdlib.h>
#include<conio.h>
#include <iostream>
#include<string>
#include<Windows.h>
//添加joystick操作api的支持库
#include<MMSystem.h>
#pragma comment(lib, "Winmm.lib")
using namespace std;
int main()
{
UINT joyNums;
joyNums = joyGetNumDevs();//读取手柄信息
printf("当前手柄数量:%d \n", joyNums);//采集手柄数量;
JOYINFO joyinfo;//定义joystick信息结构体
JOYINFOEX joyinfoex;
joyinfoex.dwSize = sizeof(JOYINFOEX);
joyinfoex.dwFlags = JOY_RETURNALL;
while (1)
{
MMRESULT joyreturn = joyGetPosEx(JOYSTICKID1, &joyinfoex);
cout << joyreturn<< endl;
cout << joyinfoex.dwXpos << endl;
Sleep(1000);
}
Sleep(3000);
return 0;
}
Windows下读取到的数据写在Joyinfoex结构体中,这里不再赘述。
stm32官方usb库移植
官方usb库下载教程。
STM32官方USB例程JoyStick详解。
移植过程可以参考正点原子教程,正点原子将回调函数写好了,但仅限打印相关提示话语,具体如何处理数据还需要自行修改。
修改为读取驾驶模拟器程序
官方库中有Joystick从机,也就是驾驶模拟器那边的例程,还有鼠标键盘读取的例程,因为鼠标键盘也是USB HID设备,我这里在正点原子提供的,移植好的鼠标键盘例程的基础上,修改为可以读取Joystick的程序。
直接用鼠标的程序,把驾驶器插进去,会有如下输出信息,说明两边USB协议层已经识别,而且驾驶模拟器这边方向盘自行转动做初始化操作,说明从机设备有响应。但显示无法识别的USB设备,推测应该是HID层的问题。
用文本搜索功能,找到回调函数中显示的内容
//usbh_usr.c文件
//无法识别的USB设备
void USBH_USR_DeviceNotSupported(void)
{
printf("无法识别的USB设备!\r\n\r\n");
}
继续搜索该回调函数,发现他是一个结构体的成员。
//usbh_usr.c文件
//USB HOST 用户回调函数.
USBH_Usr_cb_TypeDef USR_Callbacks =
{
USBH_USR_Init,
USBH_USR_DeInit,
USBH_USR_DeviceAttached,
USBH_USR_ResetDevice,
USBH_USR_DeviceDisconnected,
USBH_USR_OverCurrentDetected,
USBH_USR_DeviceSpeedDetected,
USBH_USR_Device_DescAvailable,
USBH_USR_DeviceAddressAssigned,
USBH_USR_Configuration_DescAvailable,
USBH_USR_Manufacturer_String,
USBH_USR_Product_String,
USBH_USR_SerialNum_String,
USBH_USR_EnumerationDone,
USBH_USR_UserInput,
NULL,
USBH_USR_DeviceNotSupported,
USBH_USR_UnrecoveredError
};
//usbh_core.h文件中
typedef struct _USBH_USR_PROP
{
void (*Init)(void); /* HostLibInitialized */
void (*DeInit)(voi

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



