STM32F429连接USB飞行摇杆

news2024/11/15 22:54:10

本文介绍如何使用stm32连接usb接口的飞行摇杆。

开发环境

硬件: STM32F429IGT6开发板,USB接口的飞行摇杆。

软件:STM32CubeIDE 1.11

仿真器:stlink

参考书:《圈圈教你玩USB》

USB设备描述符

一个USB设备只有一个设备描述符。USB主机通过不同种类的描述符,获得一个设备的特性。描述符的种类包括:设备描述符,配置描述符,接口描述符,端点描述符。USB描述符之间的关系是一种树状结构。设备描述符包含多个配置描述符,配置描述符包含多个接口描述符,接口描述符包含多个端点描述符。如下图所示:

STM32CubeIDE的USB HOST模块实现了USB设备通讯,实现了设备发现到设备枚举,获得描述符等一系列操作。在此基础之上,可以方便的开发USB主机模式的应用。本文使用USB HOST模块实现连接USB飞行摇杆。

建立项目

使用CubeIDE 新建一个F429项目,项目的名称为F429JoyStick。

芯片配置:

RCC

USB_OTG_FS

USB_HOST

时钟

USB使用的时钟,必须是48MHz,否则在运行代码时,通讯会失败,无法获得设备描述符。

配置完成,保存并生成代码。

USB设备处理流程

main方法循环调用MX_USB_HOST_Process(),所有USB操作都在MX_USB_HOST_Process()方法里完成。MX_USB_HOST_Process()最终会调用usbh_core.c文件里的 USBH_StatusTypeDef USBH_Process (USBH_HandleTypeDef *phost) 方法,这个方法的源代码较长。以下是这个方法的流程图:

USBH_Process()使用状态机在不同的状态之间转换,一切顺利的情况下,将会获得所有的描述符。

调试及修改

用仿真器烧录程序、调试,会发现运行到HOST_CHECK_CLASS状态时,直接跳转到了HOST_ABORT_STATE状态。问题出在这一段代码:

第714行 if (phost->pActiveClass->Init(phost) ==USBH_OK)

只有在返回值为USBH_OK时,才能转到下一个状态,否则转到HOST_ABORT_STATE状态。

phost->pActiveClass->Init(phost)调用的是usbh_hid.c文件里的static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef*phost)方法

代码如下:

USBH_HID_InterfaceInit方法继续调用USBH_FindInterface方法:

这段代码遍历&pcfg->Itf_Desc的所有接口描述符,如果有符合条件的描述符,返回描述符的序号,否则返回0xFFU。

下图是使用仿真器获得的飞行摇杆的接口描述符:

其中的pcfg->Itf_Desc[0]接口描述符里的三个值是

bInterfaceClass = 3

bInterfaceSubClass = 0

bInterfaceProtocol = 0

这三个值很重要,后面的代码修改都是围绕这三个值。

if (((pif->bInterfaceClass ==Class) || (Class == 0xFFU)) &&

((pif->bInterfaceSubClass ==SubClass) || (SubClass == 0xFFU)) &&

((pif->bInterfaceProtocol == Protocol) || (Protocol == 0xFFU)))

这个判断条件里的其他值

Class = 3

SubClass = 1

Protocol = 0xFFU

显然不满足判断语句的条件。USB HOST默认生成的代码不支持Class=3,SubClass=0,Protocol=0的USB设备。

修改USBH_HID_InterfaceInit(USBH_HandleTypeDef*phost)方法的代码,修改结果如下:

重新编译后继续调试,会发现USBH_HID_InterfaceInit(USBH_HandleTypeDef*phost)方法里的这段代码又出现了问题:

同样的道理,对于不支持的USB设备,会直接返回USBH_FAIL。为此,需要在项目里增加一个飞行摇杆设备。

增加usbh_hid_joystick.h, usbh_hid_joystick.c文件

新增文件的目录结构如下:

usbh_hid_joystick.h

usbh_hid_joystick.c

修改其他文件,修改内容如下:

增加适当的include文件后,保存所有修改,重新生成文件,调试。

将断点设置在usb_host.c的如下位置:

程序能运行到Appli_state = APPLICATION_READY这一行说明USB设备可以正常连接了。

其他

在usbh_hid_joystick.h里的PROTOLENGTH是USB数据传输时使用的长度

#define PROTOLENGTH 8

PROTOLENGTH定义的长度值需要从端点描述符里获得:

获得位置也是在USBH_HID_InterfaceInit(USBH_HandleTypeDef*phost)方法里

其中HID_Handle->length变量的值就是PROTOLENGTH需要定义的值。

usbh_hid_joystick.c :

USBH_HID_GetJoyStickInfo方法用来获得飞行摇杆的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/150405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot3.0+GraalVM搭建云原生环境

1.首先下载安装GraalVM 选择java17.windows(amd64),最好选择VPN下载 下载完成以后解压,如图 然后配置环境变量 配置GRAALVM_HOME,如图 然后在PATH里面添加 %GRAALVM_HOME%\bin 配置完成以后,在cmd里面执行java -version,可以看到jdk已经是…

Apache Shiro教程(2)

Shiro实战教程 1、权限的管理 1.1、什么是权限管理 1、基本上涉及到用户参与的系统都需要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自己被授权的资…

【 uniapp - 黑马优购 | 加入购物车】如何配置 vuex、加入购物车功能并持久化

个人名片: 🐼作者简介:一名大二在校生,讨厌编程🎋 🐻‍❄️个人主页🥇:小新爱学习. 🐼个人WeChat:hmmwx53 🕊️系列专栏:&#x1f5bc…

ABP VNext 的日志机制 + SeriLog

** ABP VNext 的日志机制 ** 正用ABP VNext做个系统,由于框架默认带来日志处理机制,开发阶段基本能用,也一直没有去动它,快要上线了,思考了一下正式环境的日志管理流程,由于系统不大,预计访问…

第一章.机器学习基本概念

第一章.机器学习基本概念 1.1 第一章.机器学习基本概念 机器学习的本质就是:寻找一个函数。 1.不同种类的函数 1).Regression:The function outputs a scalar 说明:根据今天的PM2.5的一些参数来预测明天PM2.5值 2).Classification:Given option(classes…

STL vector 模拟实现

vector 概述 vector 的数据结构安排及操作方式,与原生数组十分相似,两者唯一的差别在于空间运用的灵活性。原生数组是静态空间,一旦配置了就不能改变大小;vector 是动态空间,可以在插入过程中动态调整空间大小。vecto…

Pivoting跳板攻击

跳板攻击(Pivoting)是Meterpreter提供的一种攻击方法,允许从Meterpreter终端攻击网络中的其他系统。假如攻击者成功的入侵了一台主机,他就可以任意的利用这台机器作为跳板攻击网络中的其他系统,或者访问由于路由问题而…

【ROS】tf2_geometry_msgs 出现 No module named ‘PyKDL‘

参考文章: PyCharm单独安装PyKDL 如何在基于python3的conda虚拟环境中从头编译PyKDL 1. 问题描述 import PyKDL ModuleNotFoundError: No module named PyKDL这是由于使用的环境中不存在 PyKDL 导致的,实际上 PyKDL 在装 ROS 的时候是一起装上了&#x…

基于Springboot搭建java项目(十八)——Java线程池原理和运用

​ 在上一篇博客中有说到线程的基本原理和用法,其实Java中开辟出了一种管理线程的概念,这个概念叫做线程池,线程池的好处,就是可以方便的管理线程,也可以减少内存的消耗。那么,我们应该如何创建一个线程池&…

JAVASE 基础知识点回顾

1.关键字Static static 有三个特点,这边先阐述一下,后面代码也会展示 static 可以修饰方法(静态方法)、成员变量(静态变量),修饰不了类请注意!随着类的加载而加载,优先于对象存在,说人话就是不new 对象也…

电机专用SVPWM算法实现

SH33F2811包含三相电机的空间矢量脉宽调制(Space Vector Pulse Width Modulation,SVPWM)算法,对应于交流感应电机或永磁同步电机中的三相电压源逆变器的功率器件的一种特殊的开关触发顺序和脉宽大小的组合。这种开关触发顺序和组合…

k8s部署 wiki.js ,带中文分词

官网 https://js.wiki/ https://docs.requarks.io/install/docker-desktop k8s postgres 安装 因为包含中文分词,要在原版的基础上增加分词插件。 这里直接使用别人已经 制作好的镜像 github 地址 : https://github.com/abcfy2/docker_zhparser 镜像地址&#x…

【 java 集合】Map 接口常用方法总结

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

【面试】70道Spring Boot面试题答案

文章目录PartAPartB更多请参考来源PartA 1 什么是springboot ? 用来简化spring应用的初始搭建以及开发过程 使用特定的方式来进行配置(properties或yml文件) 创建独立的spring引用程序 main方法运行 嵌入的Tomcat 无需部署war文件 简化m…

进程控制【Linux】

1.进程终止 1.1.进程退出场景 代码运行完毕,结果正确代码运行完毕,结果不正确代码异常终止 1.2.进程常见退出方法 常见的正常中止: 从main函数return返回调用exit_exit 查看进程退出码: echo $?(查看最近一次的进程退出码) 测试代码: include &l…

【CDP】Cloudera Manager 记录一次 Service Monitor 内存溢出/使用率高的问题及解决方案

一、问题描述 最近发现我们的生产环境 Service Monitor 的监控报表数据无法正常显示,有很多的断点,有很多数据没有被正常采集到,最后定位到是 service monitor 的JVM 内存使用率过高,导致频繁GC,使得 Service Monitor…

Zynq PL DDR4读写测试工程

基于XCZU21DR-2FFVD1156E开发,本文介绍对PL DDR4的读写操作,代码全部经过上板测试。 目录 添加DDR4 IP Basic Mode and Interface & Clocking Controller Options Advanced Clocking VIO IP配置 ILA IP配置 General Options Probe_Ports(0..7…

爬虫的基本使用

文章目录urllib库1、基本使用2、一个类型、六个方法3、下载操作4、请求对象的定制5、get请求的quote方法6、get请求的urlencode方法7、post请求百度翻译8、post请求百度翻译之详细翻译小技巧:正则替换9、agax的get请求豆瓣电影第一页**10、agax的get请求豆瓣电影的前…

使用容器跑一个zabbix 监控另外一个虚机的基础项

目录 安装docker mysql数据库部署 拉取mysql镜像 运行mysql服务器 创建zabbix用户和数据库 进入docker容器登陆数据库 创建zabbix数据库创建zabbix用户 zabbix用户授权 复制mysql初始化数据库文件到容器 导入zabbix初始化数据 zabbix服务器部署 拉取镜像 运行容器 效果…

Linux环境下,JAVA环境调用C++的动态链接库so

1、使用QT开发一个动态链接库.so(本次使用linux环境,在windows下是.dll) 代码文件包含 testdll.cpp testdll.h testdll.pro testdll_global.h testdll.pro #------------------------------------------------- # # Project created by QtC…