找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 17141|回复: 19
收起左侧

基于STM32F103xx的USB转多路串口(USB-Multiple-CDC)测试已完成,全部开启DMA自动发...

  [复制链接]
ID:75926 发表于 2015-4-4 01:38 | 显示全部楼层 |阅读模式

基于STM32F103xx的USB转多路串口(USB-Multiple-CDC)测试已完成,全部开启DMA自动发送功能。简要说明如下:


1. 支持通过DMA方式连续发送超过64字节大小的数据包。而且在DMA发送的同时,继续接收来自PC主机的数据。发完64字节后,RS485不换向,可以立即发送剩余的数据。

2. USB转多路串口(USB-Multiple-CDC)支持在大虾103核心板,USB-Dual-RS485板上运行,代码无需修改。在其它板子上运行,需要修改USB控制脚和RS485控制脚。

3. 三路CDC串口,均支持DMA发送功能,接收仍为中断方式。TLL通信使用时,波特率不要超过921600bps。RS232/RS485通信时,硬件限制一般不能超过250000/500000bps。


STM32_USB-FS-Device_Lib_V7.0.0.2014.12.20_3CDC_for_DX103.zip 可不用修改直接运行在大虾103核心板上。其它STM32F103xx板子需要修改。

备注: USB-Dual-RS485板的通信部分为专用磁耦隔离的RS485芯片,只需要一个USB端口,就能同时连接两台PLC
刷新程序。目前
USB-Dual-RS485板处于缺货状态,但有大虾103核心板大量供应。

附录:“USB复合设备”和
“USB组合设备”的区别

关键字

Communication Device Class,简称CDC

USB Compound Device,USB复合设备
USB Composite Device,USB组合设备

摘要
Compound Device内嵌Hub和多个Function,每个Function都相当于一个独立的USB外设,有自己的PID/VID/DID。
Composite Device内只有一个Function,只有一套PID/VID/DID,通过将不同的interface定义为不同的类来实现
多个功能的组合。


正文
Compound Device内嵌Hub和多个Function,每个Function都相当于一个独立的USB外设,有自己的PID/VID/DID。

Composite Device内只有一个Function,只有一套PID/VID/DID,通过将不同的interface定义为不同的类来实现多个功能的组

合。很多人认为一个USB接口上实现多个设备,就是指复合设备,其实,这是不确切的,虽然USB Compound Device和USB Composite Device 都会被百度翻译为USB复合设备。

在一个USB接口上实现多个设备有2中方法,一种是Compound Device,就是复合设备;另一种是Composite Device,就是组合设备。
在USB2.0的标准协议中,定义如下:


When multiple functions are combined with a hub in a single package, they are referred to as a compound device.



A device that has multiple interfaces controlled independently of each other is referred to as a

composite device.


所以,复合设备其实就是几个设备通过一个USB Hub形成的单一设备;组合设备也就是具有多个接口的设备,每个接口代表一个独立的设备。显然,如果是想同样的功能的话,组合设备的方法要简单很多(可以去看一下USB2.0协议中,USB2.0 Hub的复杂度)。

附录:USB Serial Tools工具软件的特殊功能介绍


一般的串口调试工具,不会针对USB插拔做专门的检测和处理,比较容易崩溃,例如微软收购的超级终端等。
USB Serial Tools 是本人自2009-2012年,个人业余时间开发的一个带有USB插拔检测的串口调试软件。
和其它串口调试工具相比,是专用软件,值得一提的功能如下:
1 支持高波特率。(支持该功能的串口调试工具屈指可数,大部分串口调试工具仅支持到115200)
2 支持USB插拔检测。(支持该功能的串口调试工具屈指可数,大部分串口调试工具都会因此崩溃)
3 支持STM32虚拟串口的USB端点号显示(该工具特有的支持,和嵌入式及PC的底层驱动相关)。







1. USB数据接收及阻塞式串口发送,部分源代码浏览如下:
/* USB的OUT端点 通过物理串口向外发送数据(阻塞方式) */
#define EPx_OUT_Callback(ENDPx, USARTx, GPIOx, GPIO_Pin_x) {\
    uint32_t i;\
    uint16_t USB_Rx_Cnt;\
    USB_Rx_Cnt = USB_SIL_Read(ENDPx | 0x00, USB_Rx_Buffer); \
    GPIOx->BSRR = GPIO_Pin_x;\
    for (i = 0; i < USB_Rx_Cnt; i++) {\
        USARTx->DR = *(USB_Rx_Buffer + i);\
        while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);\
    }\
    SetEPRxValid(ENDPx);\
    while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);\
    USART_ClearFlag(USARTx, USART_FLAG_TC);\
    GPIOx->BRR = GPIO_Pin_x;\
}
2. USB数据接收及DMA式串口发送,部分源代码浏览如下
/* USB的OUT端点 通过物理串口向外发送数据(DMA方式) */
#define EPx_OUT_Callback_DMA(Flag_VCPx_Tx_Buf_Use, ENDPx, VCPx_Tx_Buffer1,VCPx_Tx_Buffer2,\
    GPIOx, GPIO_Pin_x, DMA1_Channelx, VCPx_Tx_Buffer_Cnt, Flag_VCPx_Tx_Buf_Full) {\
    uint16_t USB_Rx_Cnt;\
    if(Flag_VCPx_Tx_Buf_Use == 0){\
        USB_Rx_Cnt = GetEPRxCount(ENDPx & 0x7F);\
        PMAToUserBufferCopy(&VCPx_Tx_Buffer1[0], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
        SetEPRxValid(ENDPx);\
        GPIOx->BSRR = GPIO_Pin_x;\
        DMA1_Channelx->CNDTR = USB_Rx_Cnt;\
        DMA_Cmd(DMA1_Channelx, ENABLE);\
        Flag_VCPx_Tx_Buf_Use = 1;\
        VCPx_Tx_Buffer_Cnt = 0;\
    } else {\
        USB_Rx_Cnt = GetEPRxCount(ENDPx & 0x7F);\
        if(VCPx_Tx_Buffer_Cnt < (1024-128)){\
          PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
          VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\
          SetEPRxValid(ENDPx);\
        } else {\
          PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\
          VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\
          Flag_VCPx_Tx_Buf_Full = 1;\
        }\
    }\
}


以上两段代码是带参数的宏,由于是多个USB端点和串口之间的通信数据转发,思路是一样的,但写代码的时候,
就非常容易写错,因此用带参数的宏代替。每个虚拟串口通信函数内,都插入这些带参数的宏,编译器在编译预
处理时,会将这些宏展开, 然后再进行编译。只要调好了一个虚拟串口,另外两个就调好了,非常方便。编译器
是不会出现书写错误的。

One CDC function requires 2 IN / 1 OUT endpoints (interrupt IN/ bulk IN/ bulk OUT), other than the default EP.
Available endpoints of each STM32F family are,

STM32F102/103
- FS Device core: 7 IN / 7 OUT

STM32F105/107
- OTG_FS: 3 IN / 3 OUT

STM32F2xx/4xx
- OTG_FS: 3 IN / 3 OUT
- OTG_HS: 5 IN / 5 OUT

STM32F102/103 - 3x CDC composite
STM32F105/107 - just one CDC
STM32F2xx/4xx - 2x CDC composite on OTG_HS






评分

参与人数 1威望 +5 收起 理由
0406445 + 5 很给力!

查看全部评分

回复

使用道具 举报

ID:89891 发表于 2015-9-11 14:44 | 显示全部楼层
楼主,能给个源码呀?
回复

使用道具 举报

ID:90881 发表于 2015-9-23 15:58 | 显示全部楼层
楼主好,我正在做USB枚举3个串口的项目。想请教您一些问题。我的邮箱  550253025@qq.com,请加我好么
回复

使用道具 举报

ID:90881 发表于 2015-9-23 16:01 | 显示全部楼层
USB 转3路串口,需要创建3个cdc-acm类,还是3个实例啊?这部分不懂,请赐教
回复

使用道具 举报

ID:91616 发表于 2015-10-4 22:35 | 显示全部楼层
good!!!!!
回复

使用道具 举报

ID:74620 发表于 2016-6-22 18:31 | 显示全部楼层
想问问楼主用的单片机的具体型号,我用的是STM32F103VET6,HID模式ok,CDC插上后,连无法识别的USB提示都没有,我查的JLINK模式需要退出调试后,将单片机复位,试过后,还是觉得不行,看看你能不能给点好的建议。谢谢亲,么么哒!
回复

使用道具 举报

ID:74620 发表于 2016-6-22 18:39 | 显示全部楼层
想问问楼主用的单片机具体型号,我用的是STM32f103vet6,HID模式OK,CDC模式插上后,连无法识别的USB接口的提示都没有,希望帮忙解决一下,我的QQ是1036980828,请您有时间帮助解决下,谢谢,么么哒!
回复

使用道具 举报

ID:74620 发表于 2016-6-22 18:44 | 显示全部楼层
楼主你好,不知你用的单片机具体型号是什么,我的是STM32f103vet6,HID模式OK,CDC模式插上后连无法识别的USB提示都没有,我的QQ是1036980828,希望看到后可以给我回复,谢谢了,么么哒!
回复

使用道具 举报

ID:73429 发表于 2016-12-30 23:22 | 显示全部楼层
楼主有没有公开源码啊?还有,你写的那个串口工具,在哪里可以找到啊?
回复

使用道具 举报

ID:275678 发表于 2018-1-13 21:06 | 显示全部楼层
seven 发表于 2015-9-23 15:58
**** 作者被禁止或删除 内容自动屏蔽 ****

你好!我想问下你这个方案最后实现了吗?
回复

使用道具 举报

ID:165037 发表于 2018-6-20 09:43 | 显示全部楼层
能下载测试一下么
回复

使用道具 举报

ID:294362 发表于 2018-11-28 10:15 | 显示全部楼层
你好,楼主,组合设备的CDC设备,PC端发下来的修改CDC波特率怎么实现?怎么才能识别到是发给哪个设备的CDC?我现在改收到波特率是几个串口同时改波特率了,因无法知道是发给哪个的设备,所有只能改所有的设备波特率,无法实现独立控制,挺麻烦的!请问要如何解决?
回复

使用道具 举报

ID:294362 发表于 2018-11-28 10:20 | 显示全部楼层
你好楼主,这个组合设备CDC,如果PC端发修改波特率下来后,是发给哪个设备的要如何识别?怎么区分是发给哪个设备的?我只能控制所有设备都同时改波特率了,因为我无法区分数据是发给哪个设备的!要怎么做才能独立控制?
回复

使用道具 举报

ID:94309 发表于 2019-1-24 15:15 | 显示全部楼层
我还以为提供全部代码给我们参考呢
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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