当前位置: 首页 > news >正文

STM32组合设备实现USB转双串口

USB转双串口,核心技术就在于组合设备(USB Composite)的实现,组合设备的实现,其核心技术在于描述符的实现,下面我们先给出描述符:
设备描述符

[C]  纯文本查看 复制代码
?
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
   {
     0x12,                       /*bLength */
     USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
     0x00,                       /*bcdUSB */
     0x02,
#ifdef DUAL_COM
     0xEF,                       /*bDeviceClass*/
     0x02,                       /*bDeviceSubClass*/
     0x01,                       /*bDeviceProtocol*/
#else
     0x00,                       /*bDeviceClass*/
     0x00,                       /*bDeviceSubClass*/
     0x00,                       /*bDeviceProtocol*/       
#endif
     USB_OTG_MAX_EP0_SIZE,      /*bMaxPacketSize*/
     LOBYTE(USBD_VID),           /*idVendor*/
     HIBYTE(USBD_VID),           /*idVendor*/
     LOBYTE(USBD_PID),           /*idVendor*/
     HIBYTE(USBD_PID),           /*idVendor*/
     0x00,                       /*bcdDevice rel. 2.00*/
     0x02,
     USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
     USBD_IDX_PRODUCT_STR,       /*Index of product string*/
     USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
     USBD_CFG_MAX_NUM            /*bNumConfigurations*/
   } ; /* USB_DeviceDescriptor */


注意:双串口需要全局定义DUAL_COM宏

配置描述符是重中之重

[C]  纯文本查看 复制代码
?
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
{
   /*Configuration Descriptor*/
   0x09,   /* bLength: Configuration Descriptor size */
   USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
   0x00,
#ifdef DUAL_COM
         0x04,   /* bNumInterfaces: 4 interface */
#else
   0x02,   /* bNumInterfaces: 2 interface */
#endif
   0x01,   /* bConfigurationValue: Configuration value */
   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
   0x60,   /* bmAttributes: self powered */
   0xFA,   /* MaxPower 0 mA */
   
   /*---------------------------------------------------------------------------*/
#ifdef DUAL_COM
         // IAD
         0x08,        // bLength: Interface Descriptor size
         0x0B,                // bDescriptorType: IAD
         0x00,        // bFirstInterface
         0x02,        // bInterfaceCount
         0x02,        // bFunctionClass: CDC
         0x02,        // bFunctionSubClass
         0x01,        // bFunctionProtocol
         0x02,        // iFunction
#endif
   /*Interface Descriptor */
   0x09,   /* bLength: Interface Descriptor size */
   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
   /* Interface descriptor type */
   0x00,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x01,   /* bNumEndpoints: One endpoints used */
   0x02,   /* bInterfaceClass: Communication Interface Class */
   0x02,   /* bInterfaceSubClass: Abstract Control Model */
   0x01,   /* bInterfaceProtocol: Common AT commands */
   0x00,   /* iInterface: */
   
   /*Header Functional Descriptor*/
   0x05,   /* bLength: Endpoint Descriptor size */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x00,   /* bDescriptorSubtype: Header Func Desc */
   0x10,   /* bcdCDC: spec release number */
   0x01,
   
   /*Call Management Functional Descriptor*/
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
   0x00,   /* bmCapabilities: D0+D1 */
   0x01,   /* bDataInterface: 1 */
   
   /*ACM Functional Descriptor*/
   0x04,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
   0x02,   /* bmCapabilities */
   
   /*Union Functional Descriptor*/
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x06,   /* bDescriptorSubtype: Union func desc */
   0x00,   /* bMasterInterface: Communication class interface */
   0x01,   /* bSlaveInterface0: Data Class Interface */
   
   /*Endpoint 2 Descriptor*/
   0x07,                           /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
   CDC_CMD_EP,                     /* bEndpointAddress */
   0x03,                           /* bmAttributes: Interrupt */
   LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
   HIBYTE(CDC_CMD_PACKET_SZE),
   0xFF,                           /* bInterval: */
   
   /*---------------------------------------------------------------------------*/
   
   /*Data class interface descriptor*/
   0x09,   /* bLength: Endpoint Descriptor size */
   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
   0x01,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x02,   /* bNumEndpoints: Two endpoints used */
   0x0A,   /* bInterfaceClass: CDC */
   0x00,   /* bInterfaceSubClass: */
   0x00,   /* bInterfaceProtocol: */
   0x00,   /* iInterface: */
   
   /*Endpoint OUT Descriptor*/
   0x07,   /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
   CDC_OUT_EP,                        /* bEndpointAddress */
   0x02,                              /* bmAttributes: Bulk */
   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
   0x00,                              /* bInterval: ignore for Bulk transfer */
   
   /*Endpoint IN Descriptor*/
   0x07,   /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
   CDC_IN_EP,                         /* bEndpointAddress */
   0x02,                              /* bmAttributes: Bulk */
   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
   0x00,                              /* bInterval: ignore for Bulk transfer */
         
#ifdef DUAL_COM
         // IAD
         0x08,        // bLength: Interface Descriptor size
         0x0B,                // bDescriptorType: IAD
         0x02,        // bFirstInterface
         0x02,        // bInterfaceCount
         0x02,        // bFunctionClass: CDC
         0x02,        // bFunctionSubClass
         0x01,        // bFunctionProtocol
         0x02,        // iFunction
   /*Interface Descriptor */
   0x09,   /* bLength: Interface Descriptor size */
   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
   /* Interface descriptor type */
   0x02,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x01,   /* bNumEndpoints: One endpoints used */
   0x02,   /* bInterfaceClass: Communication Interface Class */
   0x02,   /* bInterfaceSubClass: Abstract Control Model */
   0x01,   /* bInterfaceProtocol: Common AT commands */
   0x00,   /* iInterface: */
   
   /*Header Functional Descriptor*/
   0x05,   /* bLength: Endpoint Descriptor size */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x00,   /* bDescriptorSubtype: Header Func Desc */
   0x10,   /* bcdCDC: spec release number */
   0x01,
   
   /*Call Management Functional Descriptor*/
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
   0x00,   /* bmCapabilities: D0+D1 */
   0x01,   /* bDataInterface: 1 */
   
   /*ACM Functional Descriptor*/
   0x04,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
   0x02,   /* bmCapabilities */
   
   /*Union Functional Descriptor*/
   0x05,   /* bFunctionLength */
   0x24,   /* bDescriptorType: CS_INTERFACE */
   0x06,   /* bDescriptorSubtype: Union func desc */
   0x00,   /* bMasterInterface: Communication class interface */
   0x01,   /* bSlaveInterface0: Data Class Interface */
   
   /*Endpoint 2 Descriptor*/
   0x07,                           /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
   CDC_CMD_EP,                  /* bEndpointAddress */
   0x03,                           /* bmAttributes: Interrupt */
   LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
   HIBYTE(CDC_CMD_PACKET_SZE),
   0xFF,                           /* bInterval: */
   
   /*---------------------------------------------------------------------------*/
   
   /*Data class interface descriptor*/
   0x09,   /* bLength: Endpoint Descriptor size */
   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
   0x03,   /* bInterfaceNumber: Number of Interface */
   0x00,   /* bAlternateSetting: Alternate setting */
   0x02,   /* bNumEndpoints: Two endpoints used */
   0x0A,   /* bInterfaceClass: CDC */
   0x00,   /* bInterfaceSubClass: */
   0x00,   /* bInterfaceProtocol: */
   0x00,   /* iInterface: */
   
   /*Endpoint OUT Descriptor*/
   0x07,   /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
   CDC_OUT_EP_EX,                     /* bEndpointAddress */
   0x02,                              /* bmAttributes: Bulk */
   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
   0x00,                              /* bInterval: ignore for Bulk transfer */
   
   /*Endpoint IN Descriptor*/
   0x07,   /* bLength: Endpoint Descriptor size */
   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
   CDC_IN_EP_EX,                      /* bEndpointAddress */
   0x02,                              /* bmAttributes: Bulk */
   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
   0x00                               /* bInterval: ignore for Bulk transfer */
#endif
} ;


这两个搞定,其他就是USB处理的细节问题了,包括端点的初始化,端点地址分配,数据发送接收的处理等,具体处理和实现程序可参考附件的工程源码。
成功安装驱动
<ignore_js_op> 
设备管理器里面的信息
<ignore_js_op> 
单片机程序源码: <ignore_js_op> Ginkgo_USB_COM.rar (1.06 MB, 下载次数: 2) 
PC端的驱动安装引导程序: <ignore_js_op> two_com.rar (982 Bytes, 下载次数: 2)

 

转载

转载于:https://www.cnblogs.com/Ph-one/p/4143491.html

相关文章:

  • ESP8266调试笔记
  • android驱动学习---led实验
  • 什么叫二级域名
  • 电源方案集
  • STM32.ADC
  • stm32 Flash读写[库函数]
  • strlen与sizeof区别
  • stm32 Flash读写独立函数[库函数]
  • 器件封装及尺寸问题
  • A8逻辑篇1.点亮一个LED(S5PV210.A8)
  • 电压跟随器测量
  • RC 522模块在LINUX平台调试笔记
  • RC522 模块驱动程序
  • 基于ARM、linux的MF RC522射频读卡器
  • linux体系结构与内核结构图解
  • fetch 从初识到应用
  • Hexo+码云+git快速搭建免费的静态Blog
  • input实现文字超出省略号功能
  • interface和setter,getter
  • Kibana配置logstash,报表一体化
  • Phpstorm怎样批量删除空行?
  • Terraform入门 - 3. 变更基础设施
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue.js源码(2):初探List Rendering
  • 初识 beanstalkd
  • 讲清楚之javascript作用域
  • 数据仓库的几种建模方法
  • 网页视频流m3u8/ts视频下载
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • ​卜东波研究员:高观点下的少儿计算思维
  • #define,static,const,三种常量的区别
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (一)Java算法:二分查找
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转载)Linux网络编程入门
  • * CIL library *(* CIL module *) : error LNK2005: _DllMain@12 already defined in mfcs120u.lib(dllmodu
  • ***测试-HTTP方法
  • .htaccess 强制https 单独排除某个目录
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .net 程序发生了一个不可捕获的异常
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .net开发时的诡异问题,button的onclick事件无效
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • []指针
  • [<事务专题>]
  • [ASP.NET MVC]Ajax与CustomErrors的尴尬
  • [ASP]青辰网络考试管理系统NES X3.5
  • [C++] new和delete
  • [C++] 默认构造函数、参数化构造函数、拷贝构造函数、移动构造函数及其使用案例
  • [ERROR] ocp-server-ce-py_script_start_check-4.2.1 RuntimeError: ‘tenant_name‘