STM32标准库移植USB虚拟串口,详细记录贴

文章目录

  • 前言
  • 一、移植前准备
  • 二、移植步骤
  • 1.创建文件夹,复制必要的文件
  • 2.打开工程创建文件夹,导入文件
  • 三、测试
  • 总结

  • 前言

    做项目需要使用到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还有很多的知识没有设计,欢迎各位指点
    仅作为移植记录,供后续使用,码字。累。。。

    作者:@飞翔的企鹅

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32标准库移植USB虚拟串口,详细记录贴

    发表评论