stm32 标准库移植usb usb虚拟串口 usb cdc usb转串口 保姆级记录贴


前言

做项目需要使用到usb虚拟串口功能,跟着b站一个教程移植了一遍,可以使用,在这里非常感谢up->“mandxy”。
移植一遍后后续便全部抛之脑后,所以写这片文章进行记录,以备下次移植时进行参考,同时也供有需要的人参考
usb设备分为多种,虚拟串口是属于cdc,(具体其他很多,还没学习到)
硬件:原子哥探索者开发板 stm32f407zg
软件:标准库


一、移植前准备

1.正常编译工程,我是用的是原子哥的f4标准库例程 ,“实验4 串口实验”
2.st官方usb驱动包,如下图所示
在这里插入图片描述

二、移植步骤

1.创建文件夹,复制必要的文件

1. 在工程目录下创建文件夹USB,用于存放usb驱动文件

在这里插入图片描述

2. 在usb文件夹下创建第一个文件夹USB_BOARD,用于存放板级文件。将st官方usb驱动包路径STM32_USB-Host-Device_Lib_V2.1.0\Utilities\STM32_EVAL\STM3240_41_G_EVAL中的这两个文件复制到文件夹USB_BOARD(注意我的是f4所以复制的是STM3240_41_G_EVAL文件夹中的文件,其他系列另选)
在这里插入图片描述

3. 接着在usb文件夹下创建文件夹USB_CDC,用于存放USB类文件。将st官方usb驱动包路径STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_Device_Library\Class\cdc中的这两个文件夹直接复制到文件夹USB_CDC
在这里插入图片描述然后打开复制过去的文件夹分别将没用的文件删除,两个文件夹中分别只留下usbd_cdc_core.c和usbd_cdc_core.h

4. 接着在usb文件夹下创建文件夹USB_LIB,用于存放USB库文件。将st官方usb驱动包路径STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_Device_Library\Core中的这两个文件夹直接复制到文件夹USB_LIB

在这里插入图片描述
然后打开复制过去的inc文件夹将没用的usbd_conf_template.h文件删除

5. 接着在usb文件夹下创建文件夹USB_DRIVE,用于存放USB库文件。将st官方usb驱动包路径STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_OTG_Driver中的这两个文件夹直接复制到文件夹USB_DRIVE
在这里插入图片描述
然后也是一样将没用的文件删除,删除图中选中文件

在这里插入图片描述
在这里插入图片描述

6. 接着在usb文件夹下创建文件夹USB_USER。将st官方usb驱动包路径STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP中的 inc src这两个文件夹直接复制到文件夹USB_USER
在这里插入图片描述
然后也是删除无用文件,这些文件在建好的工程里已经存在,所以删除,如下图删除选中文件
在这里插入图片描述在这里插入图片描述

到此文件夹创建完毕,文件移植完毕。

2.打开工程创建文件夹,导入文件

1. 打开移植好的工程,首先添加文件夹,导入对应文件,完成后如图所示

在这里插入图片描述

2. 添加头文件路径
在这里插入图片描述

3. 添加宏定义USE_STM324xG_EVAL和USE_USB_OTG_FS
注意宏定义间隔是“逗号”,不是“点”
USE_USB_OTG_FS:fs指的是高速设备
在这里插入图片描述
4. 进行第一次编译,应该会出现12个错误,都是头文件找不到的错误,因为根本没有添加这些头文件,根据报错把引用这些头文件的语句都屏蔽掉
这里需要注意如果像我这样对应文件上有个黄色钥匙,需要找到对应文件去除只读属性,不然无法修改

在这里插入图片描述
直接屏蔽掉报错的引用头文件语句
在这里插入图片描述
这类错误改完后编译,出现如下错误
在这里插入图片描述打开stm324xg_eval.c文件将与usb无关的函数里面的内容全部屏蔽,注意带返回值的函数使其返回0即可,led,sd,sEE,这些相关的函数内容都要屏蔽;
注意保留关于usb的函数
void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct)

在这里插入图片描述
之后打开usbd_usr.c文件,把lcd相关的初始化函数,语句等屏蔽,注意这个default:后别忘加个break;
在这里插入图片描述

之后打开usbd_cdc_vcp.c文件,找到函数
static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
这是发送函数,需要把里面内容修改为发送Buf传入的内容,原始函数是把接收到的函数又发送出去,修改后如下

static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
{
  if (linecoding.datatype == 7)
  {
//    APP_Rx_Buffer[APP_Rx_ptr_in] = USART_ReceiveData(EVAL_COM1) & 0x7F;
  }
  else if (linecoding.datatype == 8)
  {
		for(uint32_t i=0;i<Len;i++)
		{
		    APP_Rx_Buffer[APP_Rx_ptr_in++] =Buf[i];//传入要发送的数据
			
				/* To avoid buffer overflow */
				if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)	//检测接收指针长度是否达到最大值
				{
					APP_Rx_ptr_in=0;					//达到最大值清零
				}
		}
  }
  return USBD_OK;
}

再在这个文件中找到void EVAL_COM_IRQHandler(void)
数据返回屏蔽

/**
  * @brief  EVAL_COM_IRQHandler
  *         
  * @param  None.
  * @retval None.
  */
void EVAL_COM_IRQHandler(void)
{
  if (USART_GetITStatus(EVAL_COM1, USART_IT_RXNE) != RESET)
  {
    /* Send the received data to the PC Host*/
    //VCP_DataTx (0,0);
  }

  /* If overrun condition occurs, clear the ORE flag and recover communication */
  if (USART_GetFlagStatus(EVAL_COM1, USART_FLAG_ORE) != RESET)
  {
    (void)USART_ReceiveData(EVAL_COM1);
  }
}

之后打开usb_conf.h文件,找到#define VBUS_SENSING_ENABLED屏蔽掉
在这里插入图片描述

之后开始复制官方usb驱动包里main函数和中断函数里的内容到工程
1.用记事本打开官方usb驱动包里的文件app.c
路径STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP\src
全选复制到工程main.c中,(如果自己main.c中有其他有用内容不用全部复制也可以,只复制需要部分,我为了省事直接全部复制粘贴)
2.用记事本打开官方usb驱动包里的文件stm32fxxx_it.c
路径STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP\src
全选复制到工程stm32f4xx_it.c中,并修改不需要的语句错误
在这里插入图片描述

3.用记事本打开官方usb驱动包里的文件stm32fxxx_it.h
路径STM32_USB-Host-Device_Lib_V2.1.0\Project\USB_Device_Examples\VCP\inc
全选复制到工程stm32f4xx_it.h中,并修改不需要的语句错误

然后编译,我的出现几个错误,其中一个是LED的类型名重复,因为原子哥的例程中led的文件里有了led的定义,屏蔽即可
在这里插入图片描述

还有一个是没有添加stm32f4xx_exti.c文件
在这里插入图片描述还有这个报错是因为没开启c99模式
在这里插入图片描述在这里插入图片描述
修改完后编译0错误0警告
在这里插入图片描述至此移植完毕

三、测试

用usb线插入开发板对应usb口,打开设备管理器出现虚拟出来的串口com14,移植成功
在这里插入图片描述

如果听见电脑声音但没出现com口,可能是缺少usb驱动,去st官方下载对应驱动即可

在这里插入图片描述
收发测试
1.发送:
发送通过static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
这个函数实现,但是显然这个函数是个只能在usbd_cdc_vpc.c中使用,调用发送函数是通过
CDC_IF_Prop_TypeDef这个结构体来完成,

在这里插入图片描述

首先将定义好的初始化好的结构体在主函数前声明

在这里插入图片描述
调用此函数即可发送,其中有两个参数填写要发送的数据地址和长度即可
在这里插入图片描述成功接到的数据
在这里插入图片描述
2.接收:
接收函数也在usbd_cdc_vpc.c中,


static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
{
  uint32_t i;
  
  for (i = 0; i < Len; i++)
  {

  	slave_RX_data(*(Buf + i));//换成自己的接收函数即可
   //USART_SendData(EVAL_COM1, *(Buf + i) );
   // while(USART_GetFlagStatus(EVAL_COM1, USART_FLAG_TXE) == RESET); 
  } 
 
  return USBD_OK;
}


总结

完成了stm32f4系列的usb虚拟串口的移植,但仅仅是会了皮毛,usb还有很多的知识没有设计,欢迎各位指点
仅作为移植记录,供后续使用,码字。累。。。

  • 27
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值