|
基于STM32F103xx的USB轉(zhuǎn)多路串口(USB-Multiple-CDC)測(cè)試已完成,全部開(kāi)啟DMA自動(dòng)發(fā)送功能。簡(jiǎn)要說(shuō)明如下:
1. 支持通過(guò)DMA方式連續(xù)發(fā)送超過(guò)64字節(jié)大小的數(shù)據(jù)包。而且在DMA發(fā)送的同時(shí),繼續(xù)接收來(lái)自PC主機(jī)的數(shù)據(jù)。發(fā)完64字節(jié)后,RS485不換向,可以立即發(fā)送剩余的數(shù)據(jù)。
2. USB轉(zhuǎn)多路串口(USB-Multiple-CDC)支持在大蝦103核心板,USB-Dual-RS485板上運(yùn)行,代碼無(wú)需修改。在其它板子上運(yùn)行,需要修改USB控制腳和RS485控制腳。
3. 三路CDC串口,均支持DMA發(fā)送功能,接收仍為中斷方式。TLL通信使用時(shí),波特率不要超過(guò)921600bps。RS232/RS485通信時(shí),硬件限制一般不能超過(guò)250000/500000bps。
STM32_USB-FS-Device_Lib_V7.0.0.2014.12.20_3CDC_for_DX103.zip 可不用修改直接運(yùn)行在大蝦103核心板上。其它STM32F103xx板子需要修改。
備注: USB-Dual-RS485板的通信部分為專用磁耦隔離的RS485芯片,只需要一個(gè)USB端口,就能同時(shí)連接兩臺(tái)PLC
刷新程序。目前USB-Dual-RS485板處于缺貨狀態(tài),但有大蝦103核心板大量供應(yīng)。
附錄:“USB復(fù)合設(shè)備”和“USB組合設(shè)備”的區(qū)別
關(guān)鍵字
Communication Device Class,簡(jiǎn)稱CDC
USB Compound Device,USB復(fù)合設(shè)備
USB Composite Device,USB組合設(shè)備
摘要
Compound Device內(nèi)嵌Hub和多個(gè)Function,每個(gè)Function都相當(dāng)于一個(gè)獨(dú)立的USB外設(shè),有自己的PID/VID/DID。
Composite Device內(nèi)只有一個(gè)Function,只有一套PID/VID/DID,通過(guò)將不同的interface定義為不同的類來(lái)實(shí)現(xiàn)
多個(gè)功能的組合。
正文
Compound Device內(nèi)嵌Hub和多個(gè)Function,每個(gè)Function都相當(dāng)于一個(gè)獨(dú)立的USB外設(shè),有自己的PID/VID/DID。
Composite Device內(nèi)只有一個(gè)Function,只有一套PID/VID/DID,通過(guò)將不同的interface定義為不同的類來(lái)實(shí)現(xiàn)多個(gè)功能的組
合。很多人認(rèn)為一個(gè)USB接口上實(shí)現(xiàn)多個(gè)設(shè)備,就是指復(fù)合設(shè)備,其實(shí),這是不確切的,雖然USB Compound Device和USB Composite Device 都會(huì)被百度翻譯為USB復(fù)合設(shè)備。
在一個(gè)USB接口上實(shí)現(xiàn)多個(gè)設(shè)備有2中方法,一種是Compound Device,就是復(fù)合設(shè)備;另一種是Composite Device,就是組合設(shè)備。
在USB2.0的標(biāo)準(zhǔn)協(xié)議中,定義如下:
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.
所以,復(fù)合設(shè)備其實(shí)就是幾個(gè)設(shè)備通過(guò)一個(gè)USB Hub形成的單一設(shè)備;組合設(shè)備也就是具有多個(gè)接口的設(shè)備,每個(gè)接口代表一個(gè)獨(dú)立的設(shè)備。顯然,如果是想同樣的功能的話,組合設(shè)備的方法要簡(jiǎn)單很多(可以去看一下USB2.0協(xié)議中,USB2.0 Hub的復(fù)雜度)。
附錄:USB Serial Tools工具軟件的特殊功能介紹
一般的串口調(diào)試工具,不會(huì)針對(duì)USB插拔做專門(mén)的檢測(cè)和處理,比較容易崩潰,例如微軟收購(gòu)的超級(jí)終端等。
USB Serial Tools 是本人自2009-2012年,個(gè)人業(yè)余時(shí)間開(kāi)發(fā)的一個(gè)帶有USB插拔檢測(cè)的串口調(diào)試軟件。
和其它串口調(diào)試工具相比,是專用軟件,值得一提的功能如下:
1 支持高波特率。(支持該功能的串口調(diào)試工具屈指可數(shù),大部分串口調(diào)試工具僅支持到115200)
2 支持USB插拔檢測(cè)。(支持該功能的串口調(diào)試工具屈指可數(shù),大部分串口調(diào)試工具都會(huì)因此崩潰)
3 支持STM32虛擬串口的USB端點(diǎn)號(hào)顯示(該工具特有的支持,和嵌入式及PC的底層驅(qū)動(dòng)相關(guān))。


1. USB數(shù)據(jù)接收及阻塞式串口發(fā)送,部分源代碼瀏覽如下:
/* USB的OUT端點(diǎn) 通過(guò)物理串口向外發(fā)送數(shù)據(jù)(阻塞方式) */
#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數(shù)據(jù)接收及DMA式串口發(fā)送,部分源代碼瀏覽如下
/* USB的OUT端點(diǎn) 通過(guò)物理串口向外發(fā)送數(shù)據(jù)(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;\
}\
}\
}
以上兩段代碼是帶參數(shù)的宏,由于是多個(gè)USB端點(diǎn)和串口之間的通信數(shù)據(jù)轉(zhuǎn)發(fā),思路是一樣的,但寫(xiě)代碼的時(shí)候,
就非常容易寫(xiě)錯(cuò),因此用帶參數(shù)的宏代替。每個(gè)虛擬串口通信函數(shù)內(nèi),都插入這些帶參數(shù)的宏,編譯器在編譯預(yù)
處理時(shí),會(huì)將這些宏展開(kāi), 然后再進(jìn)行編譯。只要調(diào)好了一個(gè)虛擬串口,另外兩個(gè)就調(diào)好了,非常方便。編譯器
是不會(huì)出現(xiàn)書(shū)寫(xiě)錯(cuò)誤的。
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
|
評(píng)分
-
查看全部評(píng)分
|