STM32CubeIDE 简单配置USB虚拟串口 并实现printf

目录

一、MX配置

二、生成的代码

三、代码修改

1.<usbd_cdc_if.c>

2.<usbd_cdc_if.h>

3. 自定义USB初始化前的断开函数 减少复位麻烦

四、使用


一、MX配置

(支持OTG的32需要在 USB_OTG_FS中 选择 Device Only模式)

中间件Middleware配置 选择虚拟串口,参数默认即可

时钟配置 需要将USB的频率设置为48MHz

修改堆空间,避免电脑识别异常

二、生成的代码

代码文件分布结构

在main.c中已自动加入以下相关代码

#include "usb_device.h"

  MX_USB_DEVICE_Init();

三、代码修改

1.<usbd_cdc_if.c>

修改CDC_Transmit_FS函数,加入超时、判断发送结束功能,基本能保证数据发送完整。

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
  uint8_t result = USBD_OK;
  /* USER CODE BEGIN 7 */
  uint32_t TimeStart = HAL_GetTick();
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
  //if (hcdc->TxState != 0) return USBD_BUSY;
  while(hcdc->TxState)
  {
      if(HAL_GetTick()-TimeStart > 10)
	return USBD_BUSY;
      else
	break;
  }
  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
  result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
  TimeStart = HAL_GetTick();
  while(hcdc->TxState)
    {
        if(HAL_GetTick()-TimeStart > 10)
          return USBD_BUSY;
    }
  /* USER CODE END 7 */
  return result;
}

添加USB的printf函数 写在PRIVATE_FUNCTIONS_IMPLEMENTATION注释中

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */


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

/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

2.<usbd_cdc_if.h>

将void usb_printf(const char *format, ...) 同时加入<usbd_cdc_if.h>

3. 自定义USB初始化前的断开函数 减少复位麻烦

void USB_Status_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* GPIO Ports Clock Enable */
    __HAL_RCC_GPIOA_CLK_ENABLE();

    /*Configure GPIO pin Output Level */
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11 | GPIO_PIN_12, GPIO_PIN_RESET);

    /*Configure GPIO pin : W25Q256_CS_Pin */
    GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //假如不行的话,下面的延时加长即可。
    HAL_Delay(10);
}

四、使用

<main.c>中,需要准备如下代码

#include "usbd_cdc_if.h"

  /* USER CODE BEGIN SysInit */
  USB_Status_Init();
  /* USER CODE END SysInit */

业务代码 (注意:USB发送数据一定要 每包数据以末尾追加\r\n 表示一包数据接收完整)

uint8_t UserTxBuffer[] = "STM32 Virtual COM Port Driver \r\n";

CDC_Transmit_FS(UserTxBuffer, sizeof(UserTxBuffer));//方法一

usb_printf("%s\r\n",UserTxBuffer);//方法二

参考:

STM32虚拟串口usb_printf函数及接收函数

STM32CubeMX系列教程25:USB Device

  • 9
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值