完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
主机环境:Windows 7 SP1 开发环境:MDK5.18 目标板:STM32F103C8T6 开发库:STM32F1Cube库和STM32_USB_Device_Library 距离之前的STM32 USB学习又过去了N个月,想起最初想学习USB的初衷就是学习一下UVC协议,了解一下图像的传输,在逛STM32社区的时候有看到一句话:以前使用单片机必须熟悉I2C、SPI、UART等通信协议,但现在也必须熟悉USB通信协议了,因为目前主流的设备几乎都是USB接口的,在USB接口上又可以实现I2C、SPI、UART等协议,USB不可谓不强大。废话就到这吧。 经过之前的USB学习,基本上了解了STM32的USB外设,因此开始了USB接口之上的UVC的学习,中间可以说是一波三折,其中芯片还烧坏了一次,又买的新的芯片焊上去的,历史的经验告诉我们,学习一个新的东西,总不是一帆风顺的,UVC全程为USB Video Class--USB视频设备类,用于实现在USB接口上传输视频的功能,目前的UVC规范版本是1.5,可以从USB官网下载,其清单如下:
其中我们需要熟悉的是UVC 1.5 Class Specification文档,USB_Video_Example 1.5文档以及USB_Video_Payload_XX_1.5(一种)文档,由于是初学者因此这里我看的是USB_Video_Payload_MJPEG_1.5文档,也建议大家先学习该文档,毕竟新东西要从简单的开始学起。USB_Video_Example_1.5文档给出了使用MJPEG负载的示例,我们敲代码时可以用到其中的描述符。 |
|
相关推荐
|
|
这个很不错,可以
|
|
|
|
|
|
UVC规范中说明了一个UVC设备需要实现一个VC(Video Control)接口和若干个VS(Video Streaming)接口,其中VC接口用于控制设备的功能,而VS接口用于传输视频数据流。在最简单的情况下,有一个VC接口和一个VS接口,这就是接下来我们需要实现的。在未熟悉UVC规范的情况下我们也可以把代码框架搭建起来,STM32_USB_Device_Library库是一个很方便扩展的库,因为它把内核和设备类区分出来了,我们要想实现UVC就要新建一个设备类文件夹,刚好UVC和UAC有那么一点类似之处,我们可以把AUDIO中的文件拷贝一份到UVC文件夹下并修改文件名,这样我们就有了u***d_uvc以及u***d_uvc_if文件了,至于u***d_conf,u***d_desc文件只要把之前的VCP例程中的文件稍作修改就可以使用了,这样我们的UVC代码框架就算完成了,在代码实现中就要参看Example文档一步步来完善就可以了,由于是首次学习,UVC的代码框架并不是很好,因此u***d_uvc_if文件其实是没有用到的,在以后再修改吧。因为在实现中,我们只需要把视频流数据发往USB主机即可,没有什么其他的功能要实现,当然在以后有更多功能要求时类接口文件就需要好好实现了,其中u***d_uvc_if.h文件内容如下: [cpp] view plain copy
|
|
|
|
|
|
可以看到文件基本上是空的,而u***d_uvc_if.c文件内容如下:
[cpp] view plain copy
|
|
|
|
|
|
该文件也是空,但我们在UVC类文件中需要用到这个接口(为了日后扩展使用),当然如果闲麻烦的话这两个文件可以直接删除的。代码实现还是从最简单的开始即u***d_desc文件,头文件当然不需要改动了,我们改动的只有u***d_desc.c文件,在该文件中我们改动的也只是描述符而已,如下:
[cpp] view plain copy
|
|
|
|
|
|
这是从之前的VCP例程中的文件修改过来的,其中VID和PID自己随便修改吧,其中的设备描述符就需要我们注意了,这里面的内容就是我从Example文件中拷贝的,Example文档中提供了2个示例,这里我参考的是第一个示例Destop Video Camera Example,当然参考哪个示例都是可以的,该示例的框架图如下所示:
|
|
|
|
|
|
图中的概念缩写大家可以去看UVC1.5的协议规范,都有介绍的,该图只是作为参考,我在实现中省略了很多中间环节的,为了简洁而已。设备描述符的简介如下: |
|
|
|
|
|
可以看到代码中的实现跟示例是一致的,接下来就是配置描述符,也是重中之重,也是我们修改较多的地方,描述符如下 [cpp] view plain copy
|
|
|
|
|
|
对比之前的拓扑图就可以知道这里使用到了CT(相机终端),去掉了SU(选择单元)和PU(处理单元),CT直接连至OT(输出终端),这里虽然是参考的UVC1.5的文档,但最后我给改成了UVC1.1,UVC1.5其实和UVC1.1相差不多,可以使用UVCView软件来检查描述符是否正确,配置的具体含义看代码中的注释即可明白。目前UVCView只能检查UVC1.1协议,如果使用的是UVC1.5协议,该软件会提示错误,但其实并没有错误。这里是使用端点0作为默认的控制端点,使用端点1来发送视频数据流,且端点配置成同步端点。端点大小的取值在后面会解释,这里需要注意的是使用同步端点的话就一定要使用两种接口配置,默认情况下使用接口配置0,默认接口配置中不能包含数据负载非0的同步端点,只能在交替配置中包含同步端点,关于USB不同的传输类型的详细说明可以查看USB2.0协议规范的第5章节,该章节我可是仔细阅读了一下,还试着翻译了一下便于理解。也希望大家可以看看该章节以便对各个传输类型有所了解。STM32的USB模块支持全速模式即通信速率为12MBit/s,也就是1.5MByte/s,由于我的单板啥外设也没得,因此图像数据只能存储在单片机中,从STM32F1Cube中找了一张128*160的图片,来实现以15fps帧传输该图片到USB主机,该图片经过压缩成jpeg格式大概为9K字节,每秒15帧的话也就是每秒传输9K*15=135K字节,USB2.0全速模式下把1S分成了1000个微帧,即1ms为一个微帧,视频数据流在微帧内传输,全速设备在每个微帧内可以进行一次同步传输,由此得知,一次微帧我们需要传输135个字节,这里我把同步端点的最大包大小设置成150字节,足以传输这张图片了,有关为什么这里是那一张JPEG图片来传输可以查看USB_Video_Payload_MJPEG文档,MJPEG就是把一幅幅JPEG格式的帧连续的播放,因此为了简介,这里就是把一张JPEG图片连续发送到USB主机。对了,在配置描述符中有用到一个接口连接描述符,在USB设备库中是没有定义,因此把该定义加到USB设备库中,即u***d_def.h文件中,如下:
[cpp] view plain copy
|
|
|
|
|
|
至此,我们知道了所用的端点数:2个,端点类型:一个控制端点和一个同步端点,我们就可以修改u***d_conf文件了,u***d_conf.h文件如下:
[cpp] view plain copy
|
|
|
|
|
|
该文件修改不大,首先是修改端点的缓冲区地址,这里是参考UAC文件来修改的,使用双缓冲,因为STM32在把端点配置成同步端点时就自动启用了双缓冲,一开始我还想着,不使用双缓冲而使用单缓冲结构发送视频数据流,结果在测试时一直有包相同的数据跟在我发送的有效数据后面,后来在查看STM32F103C8T6参考文档时才发现,使用同步端点必须要使用双缓冲,因此,这里要配置BUF0和BUF1地址,这两个地址配成一样或不一样都不影响,因为Cube库中只对外提供了一个接口USBD_LL_Transmit,因此在USB模块使用其中一个缓冲时,应用程序也无法灵活使用另一段缓冲,再有一个修改就是MAX_STATIC_ALLOC_SIZE把值改小了,因为这里是把数据发往USB主机并不需要接口很多数据,因此,UVC的类结构并不需要使用太多的内存,u***d_conf.c文件如下:
[cpp] view plain copy
|
|
|
|
|
|
这里至改动了USBD_LL_Init()函数,配置端点1为双缓冲模式。同时在u***d_uvc.c文件中修改USBD_UVC_Init()函数打开所需的端点,如下:
[cpp] view plain copy
至此,我们就可以实现UVC设备的枚举过程了。先到这吧,未完待续。。。 |
|
|
|
|
|
楼主您好 最近也在研究UVC协议,用的无压缩格式,基本的协议也看过了,但是用UVCView去看总是提示 no open pipes。试过custom hid是可以的,但就是UVC不行,附件是UVCView的结果,能麻烦您看下吗?多谢。
|
|
|
|
|
|
[Port9] : USB Composite Device
---===>Device Information<===--- English product name: "STM32 CUSTOM HID in FS Mode" ConnectionStatus: Current Config Value: 0x01 -> Device Bus Speed: Full Device Address: 0x04 Open Pipes: 0 *!*ERROR: No open pipes!//????????????????????????????????????????????????????????????????????????????? ===>Device Descriptor<=== bLength: 0x12 bDescriptorType: 0x01 bcdUSB: 0x0200 bDeviceClass: 0xEF -> This is a Multi-interface Function Code Device bDeviceSubClass: 0x02 -> This is the Common Class Sub Class bDeviceProtocol: 0x01 -> This is the Interface Association Descriptor protocol bMaxPacketSize0: 0x40 = (64) Bytes idVendor: 0x1FC9 = Vendor ID not listed with USB.org as of 03-19-2008 idProduct: 0x17AA bcdDevice: 0x0200 iManufacturer: 0x01 English (United States) "CITIZEN" iProduct: 0x02 English (United States) "STM32 CUSTOM HID in FS Mode" iSerialNumber: 0x03 English (United States) "00000000034E" bNumConfigurations: 0x01 ===>Configuration Descriptor<=== bLength: 0x09 bDescriptorType: 0x02 wTotalLength: 0x00A7 -> Validated bNumInterfaces: 0x02 bConfigurationValue: 0x01 iConfiguration: 0x00 bmAttributes: 0x80 -> Bus Powered MaxPower: 0x7D = 250 mA ===>IAD Descriptor<=== bLength: 0x08 bDescriptorType: 0x0B bFirstInterface: 0x00 bInterfaceCount: 0x02 bFunctionClass: 0x0E -> Video Interface Class bFunctionSubClass: 0x03 -> Video Interface Collection bFunctionProtocol: 0x00 -> PC_PROTOCOL_UNDEFINED protocol iFunction: 0x02 English (United States) "STM32 CUSTOM HID in FS Mode" ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x00 bAlternateSetting: 0x00 bNumEndpoints: 0x00 bInterfaceClass: 0x0E -> Video Interface Class bInterfaceSubClass: 0x01 -> Video Control Interface SubClass bInterfaceProtocol: 0x00 iInterface: 0x02 English (United States) "STM32 CUSTOM HID in FS Mode" ===>Class-Specific Video Control Interface Header Descriptor<=== bLength: 0x0D bDescriptorType: 0x24 bDescriptorSubtype: 0x01 bcdVDC: 0x0100 wTotalLength: 0x0027 -> Validated dwClockFreq: 0x005B8D80 = (6000000) Hz bInCollection: 0x01 baInterfaceNr[1]: 0x01 USB Video Class device: spec version 1.0 ===>Video Control Input Terminal Descriptor<=== bLength: 0x11 bDescriptorType: 0x24 bDescriptorSubtype: 0x02 bTerminalID: 0x01 wTerminalType: 0x0201 = (ITT_CAMERA) bAssocTerminal: 0x00 iTerminal: 0x00 ===>Camera Input Terminal Data wObjectiveFocalLengthMin: 0x0000 wObjectiveFocalLengthMax: 0x0000 wOcularFocalLength: 0x0000 bControlSize: 0x02 bmControls : 0x00 0x00 D00 = 0 no - Scanning Mode D01 = 0 no - Auto-Exposure Mode D02 = 0 no - Auto-Exposure Priority D03 = 0 no - Exposure Time (Absolute) D04 = 0 no - Exposure Time (Relative) D05 = 0 no - Focus (Absolute) D06 = 0 no - Focus (Relative) D07 = 0 no - Iris (Absolute) D08 = 0 no - Iris (Relative) D09 = 0 no - Zoom (Absolute) D10 = 0 no - Zoom (Relative) D11 = 0 no - Pan (Absolute) D12 = 0 no - Pan (Relative) D13 = 0 no - Roll (Absolute) D14 = 0 no - Roll (Relative) D15 = 0 no - Tilt (Absolute) ===>Video Control Output Terminal Descriptor<=== bLength: 0x09 bDescriptorType: 0x24 bDescriptorSubtype: 0x03 bTerminalID: 0x02 wTerminalType: 0x0101 = (TT_STREAMING) bAssocTerminal: 0x00 bSourceID: 0x01 iTerminal: 0x00 ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x01 bAlternateSetting: 0x00 bNumEndpoints: 0x00 bInterfaceClass: 0x0E -> Video Interface Class bInterfaceSubClass: 0x02 -> Video Streaming Interface SubClass bInterfaceProtocol: 0x00 iInterface: 0x00 ===>Video Class-Specific VS Video Input Header Descriptor<=== bLength: 0x0E bDescriptorType: 0x24 bDescriptorSubtype: 0x01 bNumFormats: 0x01 wTotalLength: 0x004D -> Validated bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmInfo: 0x00 -> Dynamic Format Change not Supported bTerminalLink: 0x02 bStillCaptureMethod: 0x00 -> No Still Capture bTriggerSupport: 0x01 -> Hardware Triggering Support bTriggerUsage: 0x00 -> Host will initiate still image capture bControlSize: 0x01 Video Payload Format 1 0x00 D00 = 0 no - Key Frame Rate D01 = 0 no - P Frame Rate D02 = 0 no - Compression Quality D03 = 0 no - Compression Window Size D04 = 0 no - Generate Key Frame D05 = 0 no - Update Frame Segment D06 = 0 no - Reserved D07 = 0 no - Reserved ===>Video Streaming Uncompressed Format Type Descriptor<=== bLength: 0x1B bDescriptorType: 0x24 bDescriptorSubtype: 0x04 bFormatIndex: 0x01 bNumFrameDescriptors: 0x01 guidFormat: {3231564E-0000-0010-8000-00AA00389B71} = NV12 Format bBitsPerPixel: 0x0C bDefaultFrameIndex: 0x01 bAspectRatioX: 0x00 bAspectRatioY: 0x00 bmInterlaceFlags: 0x00 D0 = 0x00 Interlaced stream or variable: No D1 = 0x00 Fields per frame: 2 fields D2 = 0x00 Field 1 first: No D3 = 0x00 Reserved D4..5 = 0x00 Field patterns -> Field 1 only D6..7 = 0x00 Display Mode -> Bob only bCopyProtect: 0x00 -> Duplication Unrestricted ===>Video Streaming Uncompressed Frame Type Descriptor<=== --->This is the Default (optimum) Frame index bLength: 0x1E bDescriptorType: 0x24 bDescriptorSubtype: 0x05 bFrameIndex: 0x01 bmCapabilities: 0x02 wWidth: 0x0280 wHeight: 0x01E0 dwMinBitRate: 0x01C20000 dwMaxBitRate: 0x01C20000 dwMaxVideoFrameBufferSize: 0x00070800 dwDefaultFrameInterval: 0x001312D0 bFrameIntervalType: 0x01 ===>Additional Discrete Frame Type Data dwFrameInterval[1]: 0x001312D0 ===>Color Matching Descriptor<=== bLength: 0x06 bDescriptorType: 0x24 bDescriptorSubtype: 0x0D bColorPrimaries: 0x01 bTransferCharacteristics: 0x01 bMatrixCoefficients: 0x04 ===>Interface Descriptor<=== bLength: 0x09 bDescriptorType: 0x04 bInterfaceNumber: 0x01 bAlternateSetting: 0x01 bNumEndpoints: 0x01 bInterfaceClass: 0x0E -> Video Interface Class bInterfaceSubClass: 0x02 -> Video Streaming Interface SubClass bInterfaceProtocol: 0x00 iInterface: 0x00 ===>Endpoint Descriptor<=== bLength: 0x07 bDescriptorType: 0x05 bEndpointAddress: 0x83 -> Direction: IN - EndpointID: 3 bmAttributes: 0x01 -> Isochronous Transfer Type Synchronization Type = No Synchronization Bulk Transfer Type wMaxPacketSize: 0x03C2 = 0x3C2 bytes bInterval: 0x01 |
|
|
|
|
|
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
180 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
587 浏览 0 评论
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
549 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
548 浏览 0 评论
1051 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11763 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 18:46 , Processed in 0.794734 second(s), Total 66, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号