
一、我的目地:0 {$ a" K- h" k4 |; r 对于通信技术,在掌握stm32的spi,iic,USART等后,发现STM32的USB也是很好用的,对于一般的低速USB通讯任务(<1MB/s)还是可以胜任的,现在也有很多专用于USB通信的芯片,性能高于STM32的USB,但stm32的USB外设集成在了主芯片上,很便于开发。 二、我的学习过程:0 m. E9 @% G! b6 _; s' y 1、移植官方库:) g' j) R7 Q8 Y9 W" k; E( B! l (1)官方库下载后,需要根据头文件路径,设置“Option for Target”的“C/C++”选项下的“include path",之后选择自己MDK已安装的芯片类型,就可以编译了。+ |1 Z; _. _7 N (2)对于官例,参照官方的说明文档,调试基本都可以成功,但是由于st的win7驱动做的不是很好,对于usb转串口和音频输出的例程可能调试不成功。如果需要开发Windows驱动的话,这方面的知识我还在学习……Orz (3)对于我来说,官例的HID和Mass Storage是比较有用的,因为不用开发驱动(/ □ \),所以我只认真看了这俩个的官例。 2、学习USB协议" A+ l. ]- z( c2 ?2 P$ s (1)移植好STM32的官例后,想根据自己的需求更改成自己的程序,就需要学习USB的协议了,查阅USB官网,下载USB2.0的协议和HID的协议啃一啃英文文档。, K) y) n# w- _; b B: O" [ (2)在网上搜索相关USB协议的内容,论坛和电子书之类的,简单列一下我看过的比较好的一些资源,学习协议的话先看《圈圈教你玩USB》,了解一下整体开发流程,之后在看一些嵌入式开发USB的书,如《USB应用开发实例详解》和《计算机USB系统原理及其主-从机设计》,学习之后能自己编写一下上下位机的通信软件,对学习USB协议会有所帮助。 3、根据需求开发自己的上下位机( {8 M3 i6 s' k1 D G, f- [* T (1)开发上位机,用Windows的HID相关的API,开发一个基本的USB-HID通信收发程序。 (2)根据stm32的官例修改些文件,但主要是要注意修改stm32的端点收发地址,在usb_conf.h里,各个端点的地址间隔为64,及0x40,否则会丢数据的,这块而坑了我好久……(/ □ \)' C R; b2 L# }& q+ \4 i/ \. ]# k. s (3)按照HID的协议标准写好自己的描述符,这块儿知识比较杂,可以参照网上的知识,先能用再说,弄懂的话需要花些功夫啊……Orz/ p7 U4 n4 H c' }6 D6 ?7 F (4)之后就是写一些数据处理了,对于stm32的全速hid设备,使用中断协议收发数据,一包最大长度64字节,很多网上的大于64字节传输例子都是拆包实现的,这块儿也有待深学stm32的底层。0 U9 t4 v7 `/ X2 @* ^: b2 G: J6 Q 3 f/ y- J+ _ @ |
而且ST官方有个测试HID设备的Windows小软件,也很方便,省的自己开发上位机了7 o7 G2 r" W: h7 Y- P: ^
1、对HID设备的理解
(1)对于stm32的HID设备编程,最核心的就是对报告描述符的定义,具体内容在USB官网的HID版面里可以下载协议书和Usage Table来自定义HID设备;
(2)USB的官网有给一个名为HID descriptor tool的报告描述符生成工具,对于报告描述符的查错很有用,想自己写一份完整的HID报告描述符还得靠协议文档。但是可以先采用一些网上和stm32官例的代码先跑跑程序,看看效果,增加一下自己学习的动力。
2、使用HID协议的报告描述符6 F6 _, E" p- Q. l% o) F) Y
(1)在程序中我没使用报告ID,所以默认向0号ID发送包,(这里补充一下,我的自定义全速USB设备一个USB数据包为64字节,但是发送传输过程中,stm32会在之前加个报告ID,为一个字节的宽度),所以,上位机发送和接收信息只能在0号ID,其实这个ID很有用,主要是区分不同数据的,因为HID控制一般传输的都是少量字节数据,很少发整一包64字节,对于数据的分类很有帮助,而且很多HID设备都是二进制形式的状态数据,是按bit为单位进行控制通信的,用不着要收发字符串。
(2)为了通信测试,我直接按字节传输,就是上下位机收发字符串,没有对HID报告描述符的input、output和feature做太多定义
eg:
0x05, 0x8c, /* USAGE_PAGE (ST Page) */
0x09, 0x01, /* USAGE (Demo Kit) */
0xa1, 0x01, /* COLLECTION (Application) */
// The Input report # t+ @0 H, c8 Q/ R' G* }
0x09,0x01, // USAGE ID - Vendor defined % \+ D" G6 c6 O( ^+ k
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00, 0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8bit)
0x95,0x40, // REPORT_COUNT (64Byte)
0x81,0x02, // INPUT (Data,Var,Abs)
// The Output report
0x09,0x02, // USAGE ID - Vendor defined
0x15,0x00, // LOGICAL_MINIMUM (0)
0x26,0x00,0xFF, // LOGICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (8bit)
0x95,0x40, // REPORT_COUNT (64Byte)
0x91,0x02, // OUTPUT (Data,Var,Abs) ! w) |8 A0 Q d: F" o7 I
0x09,0x04, // USAGE ID - Vendor defined
0xb1,0x82, //FEATURE (Data,Var,Abs,Vol)
3 L: O# K5 S% ?. B: s
0xc0 /* END_COLLECTION */
**********之后,运行程序时,切记向0号ID传输数据,否则,发不出去也收不到……Orz+ S" |' Q) `- m
3、报告描述符书写规则0 U$ Y9 D$ v% t7 e* w* N1 G) X8 y
这个要啃USB官方的HID协议和Usage Tables那俩文件了,书写完毕后用官网给的HID descriptor tool检查一下,这里我还没有弄明白feature和report的用法,不过最好都写上,要不然可能有问题,因为我是之前没有feature,只有report,计算机是识别了,但是测试HID设备的软件识别不出output report……(/ □ \),然后加上feature就识别了,没明白是怎么一回事啊o_O
楼主有没有写上位机程序啊?