打印
[AT32F405]

【AT-START-F405测评】第二篇 使用USB-HS实现虚拟串口(CDC)

[复制链接]
3623|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
duanks|  楼主 | 2024-5-24 20:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
USB简介
雅特力已写好了非常好用的USB库,使我们无需考虑实现细节,但一些基础的内容任然需要了解
详细可以参考附件中的
AN57294 USB 101 An Introduction to Universal Serial Bus 2.0 (Chinese).pdf
usb_20.pdf
另外,在调试USB应用时,有两个很重要的软件可以帮助调试
Bus Hound监控电脑与设备的数据传输,直接对端口进行操作
USBlyzer查看设备描述符

在USB传输中,包含IN和OUT两个方向,从Host(电脑)到Device(开发板)为OUT,反之为IN,所有数据传输均只可由主机发起
所有的传输都通过端点进行,端点有一个一字节的标号,低4位标识序号,最高位表示方向(1=IN,0=OUT),例如0x81表示端点1为IN端点
端点有4种类型,control(控制),iso(同步),bulk(批量),interrupt(中断),具体描述可以看AN57294
CDC中使用了control端点(好像不用也行)和bulk端点

要知道USB设备具体是做什么的,我们需要使用描述符(Descriptor)来描述设备,其结构为一个长度+类型+内容的字符串
* Device Descriptor
  * USB版本号
  * 设备类
  * PID,VID等
* Configuration Descriptor
  * 该配置的接口数量
  * 配置编号
  * 供电等
* Interface Association Descriptor
  * 将同一功能的接口组合在一起,比如一个IAD将CDC类接口组合在一起,一个IAD将WINUSB接口组合在一起
* Interface Descriptor
  * 接口编号
  * 接口的具体类别(作用)
* Endpoint Descriptor
  * 端点类型
  * 端点大小等
* 字符串描述符
  * 在standard request->GET_DESCRIPTOR根据编号返回即可
* 类相关描述符
  * 比如CDC interface descriptor,具体看类相关的手册,如
    * CDC120-20101103-track.pdf
    * PSTN120.pdf

设置描述符
在写好描述符后,将其填入**usbd_desc_handler**结构体中,在连接电脑后,电脑首先会通过端点0发送setup包来请求描述符,这时USB库会自动返回对应的描述符

设置类的具体处理
首先是init_handler,在这里需要打开处端点0外的所有端点,做好OUT端点的接收,并初始化一些在连接时需要初始化的变量
在clear_handler中处理断开连接的的操作,比如关闭端点
在setup_handler中处理setup包,比如设置波特率,返回字符串等
在ept0_rx_handler中接收line coding数据
在in_handler和out_handler处理除端点0外其它端点数据
所有的类处理函数都放在usbd_class_handler结构体中

主要函数
在设置好描述符和处理函数后,调用usbd_init即可,所有数据处理均在回调函数中进行
* usbd_ept_recv接收OUT端点发来的数据,接收完成后由中断进入out_handler
* usbd_ept_send发送至IN端点,发送完成后进入in_handler,由于接收只能由主机发起,要处理好由于长期处于发送状态的超时问题

CDC类简介
CDC类使用一个中断IN端点处理串口命令(好像没有),一个BULK IN端点将串口接收的数据发送到电脑,一个BULK OUT端点将电脑发送的数据发输出串口
具体的CDC描述符如下
USB_DEVICE_IF_DESC_LEN,       /* bLength: interface descriptor size */
USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor
                                    type */
0x00,               /* bInterfaceNumber: number of interface */
0x00,               /* bAlternateSetting: alternate set */
0x01,               /* bNumEndpoints: number of endpoints */
USB_CLASS_CODE_CDC, /* bInterfaceClass: CDC class code */
0x02, /* bInterfaceSubClass: subclass code, Abstract Control Model*/
0x01, /* bInterfaceProtocol: protocol code, AT Command */
CDC_INT_INTERFACE_STR_IDX, /* iInterface: index of string descriptor */

0x05, /* bFunctionLength: size of this descriptor in bytes */
USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
                        */
USBD_CDC_SUBTYPE_HEADER, /* bDescriptorSubtype: Header function
                            Descriptor 0x00*/
LBYTE(CDC_BCD_NUM),
HBYTE(CDC_BCD_NUM), /* bcdCDC: USB class definitions for communications */

0x05, /* bFunctionLength: size of this descriptor in bytes */
USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
                        */
USBD_CDC_SUBTYPE_CMF,  /* bDescriptorSubtype: Call Management function
                            descriptor subtype 0x01 */
0x00,                  /* bmCapabilities: 0x00*/
0x01, /* bDataInterface: interface number of data class interface
            optionally used for call management */

0x04, /* bFunctionLength: size of this descriptor in bytes */
USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
                        */
USBD_CDC_SUBTYPE_ACM, /* bDescriptorSubtype: Abstract Control Management
                            functional descriptor subtype 0x02 */
0x02, /* bmCapabilities: Support Set_Line_Coding and Get_Line_Coding
            0x02 */

0x05, /* bFunctionLength: size of this descriptor in bytes */
USBD_CDC_CS_INTERFACE, /* bDescriptorType: CDC interface descriptor type
                        */
USBD_CDC_SUBTYPE_UFD,  /* bDescriptorSubtype: Union Function Descriptor
                            subtype 0x06 */
0x00, /* bControlInterface: The interface number of the communications
            or data class interface 0x00 */
0x01, /* bSubordinateInterface0: interface number of first subordinate
            interface in the union */

USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
                                type */
CDC_INT_EPT, /* bEndpointAddress: the address of endpoint on usb
                        device described by this descriptor */
USB_EPT_DESC_INTERRUPT, /* bmAttributes: endpoint attributes */
LBYTE(CDC_CMD_MAX),
HBYTE(CDC_CMD_MAX), /* wMaxPacketSize: maximum packe
                                        size this endpoint */
CDC_HID_BINTERVAL_TIME, /* bInterval: interval for polling endpoint for
                            data transfers */

USB_DEVICE_IF_DESC_LEN,       /* bLength: interface descriptor size */
USB_DESCIPTOR_TYPE_INTERFACE, /* bDescriptorType: interface descriptor
                                    type */
0x01,                   /* bInterfaceNumber: number of interface */
0x00,                   /* bAlternateSetting: alternate set */
0x02,                   /* bNumEndpoints: number of endpoints */
USB_CLASS_CODE_CDCDATA, /* bInterfaceClass: CDC-data class code */
0x00, /* bInterfaceSubClass: Data interface subclass code 0x00*/
0x00, /* bInterfaceProtocol: data class protocol code 0x00 */
CDC_DATA_INTERFACE_STR_IDX, /* iInterface: index of string descriptor */

USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
                                type */
CDC_BULK_IN_EPT, /* bEndpointAddress: the address of endpoint on
                            usb device described by this descriptor */
USB_EPT_DESC_BULK,    /* bmAttributes: endpoint attributes */
LBYTE(CDC_IN_MAX),
HBYTE(CDC_IN_MAX), /* wMaxPacketSize: maximum packe size
                                        this endpoint */
0x00, /* bInterval: interval for polling endpoint for data transfers */

USB_DEVICE_EPT_LEN, /* bLength: size of endpoint descriptor in bytes */
USB_DESCIPTOR_TYPE_ENDPOINT, /* bDescriptorType: endpoint descriptor
                                type */
CDC_BULK_OUT_EPT, /* bEndpointAddress: the address of endpoint on
                            usb device described by this descriptor */
USB_EPT_DESC_BULK,     /* bmAttributes: endpoint attributes */
LBYTE(CDC_OUT_MAX),
HBYTE(CDC_OUT_MAX), /* wMaxPacketSize: maximum packe
                                        size this endpoint */
0x00, /* bInterval: interval for polling endpoint for data transfers */
串口收发流程
串口收发分别使用两个数组做双缓冲,串口/USB接收/发送完成后会自动接收/发送数据,此外,每隔20ms亦会进行数据处理
CDC.zip (9.53 MB)

使用特权

评论回复
沙发
gangong| | 2024-10-28 19:59 | 只看该作者
点赞

使用特权

评论回复
板凳
黑心单片机| | 2024-11-16 19:31 | 只看该作者
我想要看你的串口双缓冲,这个我很需要

使用特权

评论回复
地板
呐咯密密| | 2024-11-19 10:06 | 只看该作者
这个代码的格式错乱了,能更正一下吗?看着太累了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

33

主题

142

帖子

2

粉丝