通过STM32CubeMx很容易生成测试代码
在左侧Connectivity中选择USART,USB_OTG_FS
在Middleware中选择USB_DEVICE,在USB_DEVICE Mode中Class For FS IP下拉框中选择Communication Device Class(Virtural Port Com)
如果需要利用Cubemx生成的代码进行移植:
1.文件需要
1.Middlewares\ST\STM32_USB_Device_Library\
Class \CDC \Inc\usbd_cdc.h \Src\usbd_cdc.c
Core\ \Inc\usbd_core.h \Src\usbd_core.c
\Inc\usbd_ctlreq.h \Src\usbd_ctlreq.c
\Inc\usbd_ioreq.h \Src\usbd_ioreq.c
2.USB_DEVICE
App\ \Inc\usb_device.h \Src\usb_device.c
\Inc\usbd_cdc_if.h \Src\usbd_cdc_if.c
\Inc\usbd_desc.h \Src\usbd_desc.c
Target\ \Inc\usbd_conf.h \Inc\usbd_conf.c
文件组织结构如下。
如果自行移植需要在中断函数中添加中断处理函数
void OTG_FS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_FS_IRQn 0 */
/* USER CODE END OTG_FS_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
/* USER CODE BEGIN OTG_FS_IRQn 1 */
/* USER CODE END OTG_FS_IRQn 1 */
}
我的测试main.c函数比较简单,生成一个递增序列,然后通过串口控制启动,通过USB的VCP类把数据发送上来。
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MPU Configuration--------------------------------------------------------*/
// MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
/* 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_USART1_UART_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
int j=0;
for(int i=0;i<2048;i++){
if((j%256==0)){
j=0;
}
Txbuff[i]=j;
j++;
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(ReceiveCplt == 1)
{
printf("%d\r\n",FrameCnt);
FrameCnt++;
CDC_Transmit_FS((uint8_t *)&head[0],8);
for(uint8_t j=0;j<16;j++)
{
for(uint8_t i=0;i<16;i++)
{
while(CDC_Transmit_FS((uint8_t*)&Txbuff[0],256)!=USBD_OK);
}
}
HAL_Delay(500);
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
串口中断处理函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
uint8_t temp;
temp=USART1->RDR; //读寄存器的值
aRxBuffer[times++] = temp; //数据暂存在一个数组中
if(temp==0x0A) //如果字符串末尾带有回车键,表明上位机发送完成
{
if(memcmp(aRxBuffer,"AT+START",8)==0)
{
times=0;
memset(aRxBuffer,0,sizeof(aRxBuffer));
ReceiveCplt=SET;
}
if(memcmp(aRxBuffer,"AT+RESET",8)==0)
{
NVIC_SystemReset();
while(1);
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}