STM32标准库移植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还有很多的知识没有设计,欢迎各位指点
仅作为移植记录,供后续使用,码字。累。。。
作者:@飞翔的企鹅