|
本帖最后由 wjandsq 于 2015-9-6 15:08 编辑 根据ST英文社区提供的资料,实现的USB转多路串口(USB-Multiple-CDC)例程,利用了STM32F103系列多端点的特性。而STM32F2/F4端点数量较少,不能实现USB-Multiple-CDC,但STM32F2/F4可以外加高速PHY芯片,实现USB2.0高速通讯。应该说F1和F2、F4使用场合不同,所以功能定位有所不同。9 v" t1 ?. M3 \" L9 i 4 q7 T* j1 M2 O( x 8 q* m# F# j. X) E( X" z- `4 H 例程包下载地址:USB-Multiple-CDC 注意事项: ) B9 ^7 M$ G" ^6 c 1.工程包中含有驱动安装引导文件。 2.3CDC工程包,属于USB转多路串口(USB-Multiple-CDC),驱动的安装可参考“USB-Dual-CDC驱动安装说明书”。 3.采用带参数的宏实现3路串口的DMA发送,这个相对于ST官方的阻塞式发送,更具有实用性。, L5 g/ n4 Q9 z6 B8 i: O : a/ w5 e) G" A2 k V, h4 n USB-Dual-CDC驱动安装说明书下载地址: USB-Dual-CDC驱动安装说明书7 [2 Z9 |$ K5 s/ i% { USB-Dual-CDC驱动安装说明书是之前USB-Dual-RS485产品的驱动安装说明书,可以参考这个安装步骤,3路的驱动,就是多安装1路而已。6 i' @7 u; s) q , {+ _& O) a9 p 三路串口的DMA发送代码部分预览如下:1 w% I/ }2 A. ?$ O$ ]+ c- O7 c /* 带参数的宏功能(预编译展开): USB的IN端点 发送数据到PC主机 */1 x/ T6 n8 |1 ?% @ #define EPx_IN_Callback(ENDPx, CDCx_Tx_State, VCPx_Rx_Buffer, VCPx_Rx_ptr_out, VCPx_Rx_length) {\ uint16_t USB_Tx_ptr;\+ w( n2 p& F3 G4 D uint16_t USB_Tx_length;\ if (CDCx_Tx_State == 1) {\ USB_Tx_ptr = VCPx_Rx_ptr_out;\ if (VCPx_Rx_length == 0) {\ CDCx_Tx_State = 0;\3 H5 K' Q. K+ v* Z7 @( b- @, ` SetEPTxCount(ENDPx,0);\) e1 f' T& c- F x! d n# a( { SetEPTxValid(ENDPx);\ } else {\ if (VCPx_Rx_length > VIRTUAL_COM_PORT_DATA_SIZE) {\ x, j+ u) t: q* _: X USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE;\ VCPx_Rx_ptr_out += VIRTUAL_COM_PORT_DATA_SIZE;\ VCPx_Rx_length -= VIRTUAL_COM_PORT_DATA_SIZE;\6 R# n$ `; c6 y) P } else {\ USB_Tx_length = VCPx_Rx_length;\% }6 k; \+ r5 h6 F% ~/ W. u( A VCPx_Rx_ptr_out += VCPx_Rx_length;\ VCPx_Rx_length = 0;\ }\6 I0 k; Z1 |4 j+ i6 S5 ^ USB_SIL_Write(ENDPx, &VCPx_Rx_Buffer[USB_Tx_ptr], USB_Tx_length);\ SetEPTxValid(ENDPx);\ }\ }\ }+ c- @4 T. ]/ O4 A0 v /* 带参数的宏功能(预编译展开): USB的OUT端点 通过物理串口向外发送数据(阻塞方式) */# w, V% J, f' P #define EPx_OUT_Callback(ENDPx, USARTx, GPIOx, GPIO_Pin_x) {\ uint32_t i;\/ R$ ~% c2 y! {4 a ? uint16_t USB_Rx_Cnt;\# T/ `2 G; c+ {% G2 { 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);\& a. I5 A1 T2 ^6 ?. M* R0 u USART_ClearFlag(USARTx, USART_FLAG_TC);\ GPIOx->BRR = GPIO_Pin_x;\, H. f3 K7 [% w% D: H3 a } /* 带参数的宏功能(预编译展开): USB的OUT端点 通过物理串口向外发送数据(DMA方式) */5 K( _0 Z( |0 R0 t) x" S #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);\8 f, Y( ^2 P D SetEPRxValid(ENDPx);\4 w; Q" U1 D; L4 w- g GPIOx->BSRR = GPIO_Pin_x;\ DMA1_Channelx->CNDTR = USB_Rx_Cnt;\* Z& ]/ k/ j+ y+ o( _ DMA_Cmd(DMA1_Channelx, ENABLE);\/ n( i7 K( R" S- B9 B1 C8 A. g, Z, H Flag_VCPx_Tx_Buf_Use = 1;\ VCPx_Tx_Buffer_Cnt = 0;\7 g8 F1 U0 H! `, j } else {\ USB_Rx_Cnt = GetEPRxCount(ENDPx & 0x7F);\ if(VCPx_Tx_Buffer_Cnt < (1024-128)){\/ b. p0 m7 m& I1 ?4 k2 p% e PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\4 a3 j- F" u1 v- _4 M- t' J VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\ SetEPRxValid(ENDPx);\ } else {\5 |& c. z4 f8 Z9 m PMAToUserBufferCopy(&VCPx_Tx_Buffer2[VCPx_Tx_Buffer_Cnt], GetEPRxAddr(ENDPx & 0x7F), USB_Rx_Cnt);\# S) ^: Y5 I1 ^0 C VCPx_Tx_Buffer_Cnt += USB_Rx_Cnt;\ Flag_VCPx_Tx_Buf_Full = 1;\$ t5 y" w% \/ W0 o& L5 g/ u. v }\ }\ } 2 K: `% c. E; k$ N4 a& t3 y) x 附录:USB Serial Tools工具软件的特殊功能介绍& Z1 S7 K% k+ ]$ A 一般的串口调试工具,不会针对USB插拔做专门的检测和处理,比较容易崩溃,例如微软收购的超级终端等。 USB Serial Tools 是本人自2009-2012年,个人业余时间开发的一个带有USB插拔检测的串口调试软件。% b* r% ~ E$ \ 和其它串口调试工具相比,是专用软件,值得一提的功能如下:& f3 ]5 Z" a" S' U! G+ a 1 支持高波特率。(支持该功能的串口调试工具屈指可数,大部分串口调试工具仅支持到115200)3 b- b- {* L( n* `( F2 e+ _! T 2 支持USB插拔检测。(支持该功能的串口调试工具屈指可数,大部分串口调试工具都会因此崩溃)6 V' U) X' H6 C1 z" m USB Serial Tools 下载地址: USB Serial Tools.zip 4 _9 C7 h4 a. E" ]$ X 1 @: w3 [$ X; n. g J' h& u& q+ x" e8 g3 X ; t6 _0 {, H( y0 b w1 n# r 9 t% M$ K6 p9 L! d' l ! f7 e4 P# _/ I4 W9 |) ], Z ; Y/ k2 [, N( l1 c- R: s ' r5 M1 p4 G, u 4 W7 a& F* {) M0 k1 Y9 a$ l$ U# Q 2 q; V/ V5 ` S( |% s * f. U& f# W. D5 c9 m; c |
USB串å£å·¥å ·æ¯æç«¯ç¹å·æ¾ç¤º
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:雨露均沾·逢7狂欢】之五:STM32系统时钟PLL故障排除1例
【福利三:雨露均沾·逢7狂欢】之三:AI帮我查BUG
福利三:雨露均沾·逢7狂欢】之二:STM32F407VG串口通信乱码故障的排除
基于STM32F103的I2C主从机通信
最全USB HID开发资料,悉心整理一个月,亲自测试
【源码】STLINK-V3MINI 高速USB仿真器,成功改刷【高速CMSIS-DAP】
OpenBLT移植到STM32F103战舰开发板上适用于所有STM32F103系列的Bootloader
TFT LCD 与 FSMC 的硬件连接大容量 STM32F10xxx FSMC 接口
单片机:初学者该了解的STM32F103基础知识
微信公众号
手机版
好东西啊!学习学习!