STM32H750 USBCDC配置与使用
- 📍相关参考文章:《STM32 USB CDC VPC》
STM32H750VB有2个USB OTG接口(1FS,1HS/FS)无晶振型解决方案,带有LPM和BCD。
-
🔖本次使用
USB-PTG-FS
作为测试
-
🌿时钟源选择内部RC振荡器
-
🌿中间件和软件配置选择
-
🌿STM32CubeMX生成的目录和文件
📗USBCDC配置功能函数配置
- 🌿实现类似
printf
打印函数:在usbd_cdc_if.c
中添加实现,将实现方法函数添加到对应的usbd_cdc_if.h
,供外部调用
/* 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 */
- 🌿实现接收超过64字节以上数据实现
同样在
usbd_cdc_if.c
中添加如下内容:
/* USER CODE BEGIN PRIVATE_VARIABLES */
USBD_CDC_LineCodingTypeDef USBD_CDC_LineCoding =
{
115200, // 默认波特率
0X00, // 1位停止位
0X00, // 无奇偶校!
0X08, // 无流控,8bit数据位4
};
uint8_t Rx_Buffer[Rx_Buffer_Len];//全局变量,添加到usbd_cdc_if.h中
__IO uint8_t DataReceive_Flag;//全局变量,添加到usbd_cdc_if.h中
uint32_t SinglePackLength;
uint8_t *p_TempBuf;
uint8_t Num_Packet;
uint32_t Rx_Data_Len;//全局变量,添加到usbd_cdc_if.h中
/* USER CODE END PRIVATE_VARIABLES */
- 🌿函数:
CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
,主要是实现监听虚拟端口波特率的变化。
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:
USBD_CDC_LineCoding.bitrate = (pbuf[3] << 24) | (pbuf[2] << 16) | (pbuf[1] << 8) | pbuf[0];
USBD_CDC_LineCoding.format = pbuf[4];
USBD_CDC_LineCoding.paritytype = pbuf[5];
USBD_CDC_LineCoding.datatype = pbuf[6];
// huart1.Init.BaudRate = USBD_CDC_LineCoding.bitrate;
// HAL_UART_Init(&huart1);
break;
case CDC_GET_LINE_CODING:
pbuf[0] = (uint8_t)(USBD_CDC_LineCoding.bitrate);
pbuf[1] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 8);
pbuf[2] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 16);
pbuf[3] = (uint8_t)(USBD_CDC_LineCoding.bitrate >> 24);
pbuf[4] = USBD_CDC_LineCoding.format;
pbuf[5] = USBD_CDC_LineCoding.paritytype;
pbuf[6] = USBD_CDC_LineCoding.datatype;
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
- 🌿接收数据函数:
CDC_Receive_FS
补充:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
// CDC_Transmit_FS(Buf, *Len); //将接收到的数据,从USB串口 再发送出去
p_TempBuf = Buf;
SinglePackLength = *Len;
if (SinglePackLength == CDC_DATA_FS_MAX_PACKET_SIZE)
{
memcpy((Rx_Buffer + (CDC_DATA_FS_MAX_PACKET_SIZE * Num_Packet)), Buf, SinglePackLength);
Rx_Data_Len = (CDC_DATA_FS_MAX_PACKET_SIZE * Num_Packet) + SinglePackLength;
Num_Packet++;
}
else
{
memcpy((Rx_Buffer + (CDC_DATA_FS_MAX_PACKET_SIZE * Num_Packet)), Buf, SinglePackLength);
Rx_Data_Len = (CDC_DATA_FS_MAX_PACKET_SIZE * Num_Packet) + SinglePackLength;
DataReceive_Flag = 1;
Num_Packet = 0;
}
return (USBD_OK);
/* USER CODE END 6 */
}
- 🌿对从虚拟端口接收到的数据处理内容:
if(DataReceive_Flag){
DataReceive_Flag =0;
// printf("cdc rece:%s",Rx_Buffer);
SCB_CleanDCache_by_Addr((uint32_t *)Rx_Buffer, Rx_Buffer_Len);
// SCB_CleanInvalidateDCache_by_Addr ((uint32_t *)UART_RX_STA, UART_RX_LEN);//或者
HAL_UART_Transmit_DMA(&huart1,(uint8_t *)Rx_Buffer, Rx_Data_Len);//配合上面的函数一起使用
//HAL_UART_Transmit(&huart1, Rx_Buffer, Rx_Buffer_Len, 100);
}
- 📜测试效果: