使用cubeide配置usb虚拟串口
工程配置
新建一个stm32工程,配置好时钟,其中USB配置48MHz
修改堆空间大小,如果太小会导致无法识别usb设备
使能USB资源,选择模式配置为Device Only
Middleware配置选择虚拟串口
以上配置完成以后生成代码
软件配置
解决不同版本固件库导致的无法连接
修改CDC_Control_FS函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| USBD_CDC_LineCodingTypeDef linecoding = { 115200, /* baud rate*/ 0x01, /* stop bits-1*/ 0x00, /* parity - none*/ 0x08 /* nb. of bits 8*/ };
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) { /* USER CODE BEGIN 5 */ switch(cmd) { case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/ /* Line Coding Structure */ /*-----------------------------------------------------------------------------*/ /* Offset | Field | Size | Value | Description */ /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/ /* 4 | bCharFormat | 1 | Number | Stop bits */ /* 0 - 1 Stop bit */ /* 1 - 1.5 Stop bits */ /* 2 - 2 Stop bits */ /* 5 | bParityType | 1 | Number | Parity */ /* 0 - None */ /* 1 - Odd */ /* 2 - Even */ /* 3 - Mark */ /* 4 - Space */ /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */ /*******************************************************************************/ case CDC_SET_LINE_CODING: linecoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ (pbuf[2] << 16) | (pbuf[3] << 24)); linecoding.format = pbuf[4]; linecoding.paritytype = pbuf[5]; linecoding.datatype = pbuf[6]; break;
case CDC_GET_LINE_CODING: pbuf[0] = (uint8_t)(linecoding.bitrate); pbuf[1] = (uint8_t)(linecoding.bitrate >> 8); pbuf[2] = (uint8_t)(linecoding.bitrate >> 16); pbuf[3] = (uint8_t)(linecoding.bitrate >> 24); pbuf[4] = linecoding.format; pbuf[5] = linecoding.paritytype; pbuf[6] = linecoding.datatype; break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default: break; }
return (USBD_OK); /* USER CODE END 5 */ }
|
发送数据
发送数据只要调用函数即可,比较简单,需要注意的是长度必须是32bit对齐,如果数据少了会强制补齐
1
| CDC_Transmit_FS(UserTxBufferFS, length);
|
格式化输出
在usbd_cdc_if.c添加格式化输出函数,最大输出长度可配置
1 2 3 4 5 6 7 8 9 10 11 12
| #include <stdarg.h> void usb_printf(const char *format, ...) { va_list args; uint32_t length; va_start(args, format); length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args); va_end(args); CDC_Transmit_FS(UserTxBufferFS, length); }
|
接收数据
单次接收的最大数据量为64byte
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */
__disable_irq(); for( uint32_t i = 0; i < *Len; i ++ ){ rxData[rxLen+i] = Buf[i]; } rxLen += *Len; __enable_irq();
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hUsbDeviceFS); //CDC_Transmit_FS( Buf, *Len ); return (USBD_OK); /* USER CODE END 6 */ }
|