目錄
1.<usbd_cdc_if.c>
2.<usbd_cdc_if.h>
一、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);//方法二
參考: