请选择 进入手机版 | 继续访问电脑版
搜索
查看: 748|回复: 8

[分享] 【实战经验】通过STM32CubeMX生成HID双向通讯工程

[复制链接]

401

主题

1653

帖子

2

精华

Rank: 9Rank: 9Rank: 9

管理员

注册时间
2016-6-1
发表于 2016-7-12 14:57:03 | 显示全部楼层 |阅读模式
通过STM32CubeMX生成HID双向通讯工程
前言
客户在做USB通讯的时候,基本的需求就是发送某些数据到USB host端,同时接收一些数据从USB Host端,那么如何快速的建立一个工程并验证数据是否正确呢?下边我们就结合STM32F072的评估板(其他的STM32xx系列的实现方式都是类似的)来快速实现一个简单的数据收发实验。

问题分析
USB Host软件
PC端软件使用ST免费提供的Usb Hid Demonstrator。这个软件可以在ST官网上免费下载到。连接地址:STSW-STM32084,此软件调用的是windows标准的HID类驱动,所以无需安装任何驱动程序及可运行。



下载安装完这个软件之后,我们就可以开始开发STM32的USB 从机程序了。
首先,打开STM32CubeMX,新建工程,选择STM32F072B-DISCOVERY开发板。



其次,在Pinout选项中,开打USB的device功能。



并在Middleware中选择开启class for IP中的 custom Human Interface Device(HID).



点击“保存”后直接生成工程。我们这里以生成IAR工程为例,项目名叫做HID。



这样我们的工程就基本成功了,但是还缺少最最关键的一步,就是USB主机和从机的通讯“协议”,这个协议在那里实现呢?因为我们Host端软件已经是Usb Hid Demonstrator,那么这边的协议就已经固定了(其实在实际的开发中大多是主机端和从机相互沟通后,软件自行修改的),从机只需要对应这套协议即可。
将如下代码复制,替换掉usbd_custom_hid_if.c文件中的同名数组。






注意:这里一定要覆盖“同名”数组,千万不要覆盖错了。
之后将如下代码复制到usbd_custom_hid_if_if.h中。



最后在usbd_conf.h文件中将USBD_CUSTOM_HID_REPORT_DESC_SIZE的定义值修改为163(默认值是2)

为什么这样修改呢? 简单说一下其中关键值的含义。这个HID 的报文描述符其实定义了8个部分(条目)的功能定义,分为LED1,LED2,LED3,LED4,按键输入,篡改按键输入和ADC输入。每一个部分基本的格式都是固定的。以LED1为例(其他条目可自行对照文档解析):

0x85, LED1_REPORT_ID, 含义是这个功能的ID号是LED1_REPORT_ID(宏定义为0x01)
这个ID号是每次报文发送的时候最先被发送出去的(USB都是LSB)字节,之后跟着的才是我们实际有效的数据/指令,到底是数据还是指令,就看你的应用程序如何去解析这个数据了。

0x09, 0x01, 这个功能序号为1,后边的序号依次递加,没什么好说的
0x15, 0x00, 这个是规定逻辑最小值为0
0x25, 0x01, 这个是规定逻辑最大值为1
上边的这两条语句规定了跟在报文ID后边的数据范围,最大值是1,最小值是0.(因为我们的LED也就只有灭和亮两种状态)

0x75, 0x08, 这个是报文的大小为8,只要别写错就行了
0x95, LED1_REPORT_COUNT, 这个是说下边有LED1_REPORT_COUNT (宏定义为1)个项目会被添加,即这个功能的数量是1个
0xB1, 0x82, 这个是规定能够发送给从机设备的数据信息
0x91, 0x82, 这个规定了这个功能的数据方向是输出(USB的方向都是针对主机来说的)
总结一下,通过这个报文描述符,我们就告诉了主机,在HID中有一个功能ID为1的功能,其方向是从主机到从机,每次发送1个有效数据(前边的ID是都要含有的),这个数据可以是0或者是1.
关于HID 报文描述符的详细信息,您可以在下边的网址下载一篇叫做《Device Class Definition for HID》的文档来参考。
http://www.usb.org/developers/hidpage

这样基本的程序框架就已经成功了。此时我们可以先编译一下,看看是否有任何遗漏的或者笔误。如果编译是正确的,那么我们就可以先下载到硬件开发板上,连接到PC端,看看是否可以枚举出设备。如果您前边的修改都是正确的,那么在PC的设备管理器中会看到如下图所示的内容。



注意:开发板上有两个一模一样的Mini USB接口,一个是USB USER,另 一个是USB ST-link,下载代码的时候用USB ST-Link,连接电脑运行程序的时候要用USB USER。
此时我们的USB枚举就完成了,这个是USB通讯的关键步骤,之后的应用通讯内容都是通过这个枚举工程来进行“规划”的。

数据发送
就类似串口通讯,我们首先做一个数据的发送工作。
在Main.c文件中,我们在while(1)的主循环中增加我们的发送函数,主要就是调用发送报文的API:USBD_CUSTOM_HID_SendReport()



编译后下载到MCU内,连接上位机软件即可看到如下所示的进度条在不断的增长。



这个就是我们上传到的数据在上位机的图形显示,你也可以看Input/output transfer里的数据变化。



这样看起来是不是更像是串口调试助手了?嘿嘿 本来机制就差不多的。

数据接收
MCU的USB数据是如何接收的呢?是不调用一个类似于串口接收的API呢?
不是的!USB的数据接收都是在中断中完成的,在新建的工程中,我们在函数CUSTOM_HID_OutEvent_FS内增加如下代码。



编译之后下载到MCU内,通过USB USER连接到PC端,打开Usb Hid Demonstrator,我们可以通过勾选右下角的图形界面来实现控制开发板上的LED电量或者关闭。



当然,这个是通过图像化的界面来进行控制,你也可以通过Input/output transfer中的写入对话框来完成这个操作。注意,写入的第一个字节是ID,表示你想控制的是哪个LED;第二个字节是0或者是1,表示你想让这个LDE的状态变成灭还是亮。



总结: 本范例程序是为了快速实现USB 从机设备与主句设备双向通讯目的,其初始化代码是用STM32CubeMX来生成的,大大降低了工程师开发USB设备的难度(尤其是是入门阶段的难度)。从这个工程的基础上,工程师可以比较方便的建立好框架工程并,对其中的代码进行研究,进而移植或增加自己的应用代码。

文档和代码下载地址:
http://www.stmcu.org/document/detail/index/id-217181


工程

17.png(37.22 KB, 下载次数: 0)



16.png(37.78 KB, 下载次数: 0)



15.png(52.58 KB, 下载次数: 0)



14.png(34.56 KB, 下载次数: 0)



13.png(38.14 KB, 下载次数: 0)




文档和代码下载地址:
http://www.stmcu.org/document/detail/index/id-217181


实战经验汇总:
http://www.stmcu.org/module/forum/thread-576401-1-1.html
欢迎加入STM32/STM8社区技术交流群: 330177207    STM32L系列开发群:571793578
回复

使用道具 举报

0

主题

13

帖子

0

精华

Rank: 1

新手上路

注册时间
2016-7-13
发表于 2016-7-13 08:57:33 | 显示全部楼层
谢谢楼主!学习了
回复 支持 反对

使用道具 举报

0

主题

69

帖子

0

精华

Rank: 3Rank: 3

中级会员

注册时间
2015-1-9
发表于 2016-7-13 11:01:35 | 显示全部楼层
mark,谢谢楼主的资料分享
欢迎加入STM32/STM8社区技术交流群: 330177207    STM32L系列开发群:571793578
回复 支持 反对

使用道具 举报

2

主题

46

帖子

0

精华

Rank: 2

初级会员

注册时间
2015-4-1
发表于 2016-7-13 11:54:38 | 显示全部楼层
谢谢楼主!学习了
回复 支持 反对

使用道具 举报

59

主题

2644

帖子

0

精华

Rank: 8Rank: 8

论坛元老

注册时间
2010-4-9
发表于 2016-7-25 09:47:41 | 显示全部楼层
欢迎加入STM32/STM8社区技术交流群: 330177207    STM32L系列开发群:571793578
回复

使用道具 举报

0

主题

2

帖子

0

精华

Rank: 2

初级会员

注册时间
2015-9-1
发表于 2016-12-13 08:32:49 | 显示全部楼层
很好的例程~谢谢
回复 支持 反对

使用道具 举报

6

主题

443

帖子

0

精华

Rank: 6Rank: 6

金牌会员

注册时间
2016-4-23
发表于 2016-12-31 02:37:11 | 显示全部楼层
宝贵的实战经验
欢迎加入STM32/STM8社区技术交流群: 330177207    STM32L系列开发群:571793578
回复 支持 反对

使用道具 举报

7

主题

445

帖子

1

精华

Rank: 6Rank: 6

金牌会员

注册时间
2016-8-2
发表于 2017-1-2 14:11:40 | 显示全部楼层
回复

使用道具 举报

3

主题

50

帖子

0

精华

Rank: 3Rank: 3

中级会员

注册时间
2015-8-5
发表于 2017-1-12 11:09:44 | 显示全部楼层
本帖最后由 tanr 于 2017-1-12 11:11 编辑

如果不在main函数中的while中调用USBD_CUSTOM_HID_SendReport()这个函数,为什么就不能继续使用HID了,有大神为我指点迷津不
欢迎加入STM32/STM8社区技术交流群: 330177207    STM32L系列开发群:571793578
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

Archiver|手机版|小黑屋|意法半导体STM32/STM8技术社区    

GMT+8, 2017-2-26 16:19 , Processed in 0.362951 second(s), 12 queries , Memcache On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表