stm32Cubemx USB虚拟串口

CubeMx配置

时钟:
stm32Cubemx USB虚拟串口_第1张图片
选择USB_OTG_FS->Mode->Device_Only,其余默认即可stm32Cubemx USB虚拟串口_第2张图片
USB_DEVICE->Class For FS IP选择虚拟串口,其余不变
stm32Cubemx USB虚拟串口_第3张图片
修改Heap Size 大小,小了会识别到USB造成驱动设备出现感叹号
stm32Cubemx USB虚拟串口_第4张图片
stm32Cubemx USB虚拟串口_第5张图片

代码

编写连接情况查询函数:
hUsbDeviceFS定义在usb_device.c中

void VCP_Status(void)
{
    static uint8_t old_status = 0;
 
    if(hUsbDeviceFS.dev_state != old_status)
    {
        if(hUsbDeviceFS.dev_state == USBD_STATE_CONFIGURED)
            printf("连接成功\r\n");
        else if (hUsbDeviceFS.dev_state == USBD_STATE_SUSPENDED)
            printf("断开成功\r\n");
        old_status = hUsbDeviceFS.dev_state;
    }    
}

编写USB发送函数usb_printf():放置于usbd_cdc_if.c文件的
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION /
/
USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */中,并在usbd_cdc_if.h声明

#include 
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);
}

在usbd_cdc_if.c文件的
/* USER CODE BEGIN PRIVATE_VARIABLES /
/
USER CODE END PRIVATE_VARIABLES */位置添加结构体定义:用于接收

typedef struct{
  uint32_t rxlen;
  uint32_t flag;
}VcpRx_t;
 
VcpRx_t temp = {
    .rxlen =0,
    .flag = 0
};

相同文件下,修改static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)函数,修改后为
注:发送时每次发送必须以\r\n结尾

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
    temp.rxlen = temp.rxlen + (*Len);
    
    if(temp.rxlen < APP_RX_DATA_SIZE && UserRxBufferFS[temp.rxlen - 2] != 0x0d  \
        &&  UserRxBufferFS[temp.rxlen - 1] != 0x0a)//***发送时每次发送必须以\r\n结尾***
    {
       //---继续接收---------------
       USBD_CDC_SetRxBuffer(&hUsbDeviceFS,UserRxBufferFS  + temp.rxlen); 
       USBD_CDC_ReceivePacket(&hUsbDeviceFS);
    }
    else 
    {
       temp.flag = 1;    //接收完成
       UserRxBufferFS[temp.rxlen] = 0;
    }
    return (USBD_OK);	
  /* USER CODE END 6 */
}

编写USB发送函数rxdata_printf():放置于usbd_cdc_if.c文件的
/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION /
/
USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */中,并在usbd_cdc_if.h声明

//接收完成后通过usb回发数据
void rxdata_printf(void)
{
  if(temp.flag)
  {
    usb_printf("%s\r\n", UserRxBufferFS);//若无需回发,屏蔽即可
    temp.flag = 0;
    temp.rxlen = 0;
    memset(UserRxBufferFS, 0, APP_RX_DATA_SIZE);
    USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS); 
    USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  }
}

主函数

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USB_DEVICE_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//CDC_Transmit_FS((uint8_t *)"无Fuck说!\n",sizeof("无Fuck说!\n"));//也可这样发送
		usb_printf("发送数据\r\n");
		HAL_Delay(500);
		rxdata_printf();
  }
  /* USER CODE END 3 */
}

stm32Cubemx USB虚拟串口_第6张图片
波特率随便设,没有固定
参考:https://blog.csdn.net/sudaroot/article/details/86627853

你可能感兴趣的:(STM32)