博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
STM32 USB转串口分析
阅读量:4086 次
发布时间:2019-05-25

本文共 9536 字,大约阅读时间需要 31 分钟。

STM32 USB转串口分析

芯片:STM32F407VE

编译器:KEIL5

作者:SY

日期:2017-9-18 09:56:00

概述

使用 STM32_USB-Host-Device_Lib_V2.2.0 usb 库,将 stm32 作为 usb 设备,实现 usb 转串口的功能。

移植

按照例程添加相关文件后测试,主机端使用 Windows7 X64 ,可以正常识别 usb 设备,Windows 安装驱动后提示:驱动不能正常工作

原因

可能是需要主机端安装 USB 转串口驱动。

解决

网上搜索后,安装 stmcdc.ini

;------------------------------------------------------------------------------; STMicroelectronics Comunication Device Class driver (CDC) INF FILE; (C)2010 Copyright STMicroelectronics;------------------------------------------------------------------------------[Version]Signature="$Windows NT$"Class=PortsClassGuid={
4D36E978-E325-11CE-BFC1-08002BE10318}Provider=%PRVDR%CatalogFile=stmcdc.catDriverVer=04/25/2010,1.3.1[SourceDisksNames]1=%DriversDisk%,,,[SourceDisksFiles][Manufacturer]%MFGNAME%=DeviceList,NT,NTamd64[DestinationDirs]DefaultDestDir = 12;------------------------------------------------------------------------------; VID/PID Settings;------------------------------------------------------------------------------[DeviceList.NT]%DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5740[DeviceList.NTamd64]%DESCRIPTION%=DriverInstall,USB\VID_0483&PID_5740[DriverInstall.NT]Include=mdmcpq.infCopyFiles=FakeModemCopyFileSectionAddReg=DriverInstall.NT.AddReg[DriverInstall.NT.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,usbser.sysHKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"[DriverInstall.NT.Services]AddService=usbser, 0x00000002, DriverServiceInst[DriverServiceInst]DisplayName=%SERVICE%ServiceType = 1 ; SERVICE_KERNEL_DRIVERStartType = 3 ; SERVICE_DEMAND_STARTErrorControl = 1 ; SERVICE_ERROR_NORMALServiceBinary= %12%\usbser.sysLoadOrderGroup = Base;------------------------------------------------------------------------------; String Definitions;------------------------------------------------------------------------------[Strings]PRVDR = "STMicroelectronics"MFGNAME = "STMicroelectronics."DESCRIPTION = "STMicroelectronics Virtual COM Port"SERVICE = "STM Virtual COM Port"DriversDisk = "STM Drivers Disk"

测试驱动还是不能正常工作

网上搜索发现有驱动安装包的形式:VCP_V1.4.0_Setup.exe ,遂安装,发现还是不能正常工作。

原因

怀疑可能是从机没有移植好,采用 STM32CubeMX 软件自动生成一份下位机程序,测试下来还是和以前移植的程序现象一样

解决

网上搜索原因: ,原来是 malloc 内存分配失败,扩大堆内存后,终于驱动安装成功了!

原因

既然 STM32CubeMX 可以成功,应该问题就是出在初始化阶段,仿真仔细排查:

uint8_t  usbd_cdc_Init (void  *pdev,                                uint8_t cfgidx){  uint8_t *pbuf;  /* Open EP IN */  DCD_EP_Open(pdev,              CDC_IN_EP,              CDC_DATA_IN_PACKET_SIZE,              USB_OTG_EP_BULK);}

隐约感觉 CDC_DATA_IN_PACKET_SIZE 可能会有问题,查看来源:

#define CDC_DATA_IN_PACKET_SIZE                CDC_DATA_MAX_PACKET_SIZE#define CDC_DATA_MAX_PACKET_SIZE                512  /* Endpoint IN & OUT Packet size */

问题应该出在这里了,我的 usb 使用的是 usb-hs 高速接口,但是物理层仍然使用内部的 phy ,这样使用起来简单,但是最大速度只能达到全速的速度12Mbps ,而全速设备的最大包大小为 64 字节。修改后,测试终于成功了。而且不需要安装任何第三方驱动!

移植过程中最终要的文件:usbd_cdc_vcp.c

/**  ******************************************************************************  * @file    usbd_cdc_vcp.c  * @author  MCD Application Team  * @version V1.2.0  * @date    09-November-2015  * @brief   Generic media access Layer.  ******************************************************************************  * @attention  *  * 

© COPYRIGHT 2015 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED #pragma data_alignment = 4 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED *//* Includes ------------------------------------------------------------------*/#include "usbd_cdc_vcp.h"#include "stm32f4xx.h"/* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*/LINE_CODING linecoding = { 115200, /* baud rate*/ 0x00, /* stop bits-1*/ 0x00, /* parity - none*/ 0x08 /* nb. of bits 8*/ };USART_InitTypeDef USART_InitStructure;/* These are external variables imported from CDC core to be used for IN transfer management. */extern uint8_t APP_Rx_Buffer []; /* Write CDC received data in this buffer. These data will be sent over USB IN endpoint in the CDC core functions. */extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to start address when writing received data in the buffer APP_Rx_Buffer. *//* Private function prototypes -----------------------------------------------*/static uint16_t VCP_Init (void);static uint16_t VCP_DeInit (void);static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);static uint16_t VCP_DataTx (void);static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len);static uint16_t VCP_COMConfig(uint8_t Conf);CDC_IF_Prop_TypeDef VCP_fops = { VCP_Init, VCP_DeInit, VCP_Ctrl, VCP_DataTx, VCP_DataRx};static uint8_t g_RxByte;/* Private functions ---------------------------------------------------------*//** * @brief VCP_Init * Initializes the Media on the STM32 * @param None * @retval Result of the operation (USBD_OK in all cases) */static uint16_t VCP_Init(void){ return USBD_OK;}/** * @brief VCP_DeInit * DeInitializes the Media on the STM32 * @param None * @retval Result of the operation (USBD_OK in all cases) */static uint16_t VCP_DeInit(void){ return USBD_OK;}/** * @brief VCP_Ctrl * Manage the CDC class requests * @param Cmd: Command code * @param Buf: Buffer containing command data (request parameters) * @param Len: Number of data to be sent (in bytes) * @retval Result of the operation (USBD_OK in all cases) */static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len){ switch (Cmd) { case SEND_ENCAPSULATED_COMMAND: /* Not needed for this driver */ break; case GET_ENCAPSULATED_RESPONSE: /* Not needed for this driver */ break; case SET_COMM_FEATURE: /* Not needed for this driver */ break; case GET_COMM_FEATURE: /* Not needed for this driver */ break; case CLEAR_COMM_FEATURE: /* Not needed for this driver */ break; case SET_LINE_CODING: linecoding.bitrate = (uint32_t)(Buf[0] | (Buf[1] << 8) | (Buf[2] << 16) | (Buf[3] << 24)); linecoding.format = Buf[4]; linecoding.paritytype = Buf[5]; linecoding.datatype = Buf[6]; /* Set the new configuration */ VCP_COMConfig(OTHER_CONFIG); break; case GET_LINE_CODING: Buf[0] = (uint8_t)(linecoding.bitrate); Buf[1] = (uint8_t)(linecoding.bitrate >> 8); Buf[2] = (uint8_t)(linecoding.bitrate >> 16); Buf[3] = (uint8_t)(linecoding.bitrate >> 24); Buf[4] = linecoding.format; Buf[5] = linecoding.paritytype; Buf[6] = linecoding.datatype; break; case SET_CONTROL_LINE_STATE: /* Not needed for this driver */ break; case SEND_BREAK: /* Not needed for this driver */ break; default: break; } return USBD_OK;}/** * @brief VCP_DataTx * CDC received data to be send over USB IN endpoint are managed in * this function. * @param Buf: Buffer of data to be sent * @param Len: Number of data to be sent (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL */static uint16_t VCP_DataTx (void){ if (linecoding.datatype == 7) { APP_Rx_Buffer[APP_Rx_ptr_in] = g_RxByte & 0x7F; } else if (linecoding.datatype == 8) { APP_Rx_Buffer[APP_Rx_ptr_in] = g_RxByte; } APP_Rx_ptr_in++; /* To avoid buffer overflow */ if(APP_Rx_ptr_in == APP_RX_DATA_SIZE) { APP_Rx_ptr_in = 0; } return USBD_OK;}/** * @brief VCP_DataRx * Data received over USB OUT endpoint are sent over CDC interface * through this function. * * @note * This function will block any OUT packet reception on USB endpoint * until exiting this function. If you exit this function before transfer * is complete on CDC interface (ie. using DMA controller) it will result * in receiving more data while previous ones are still not sent. * * @param Buf: Buffer of data received * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else VCP_FAIL */static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len){ for (uint32_t i=0; i

实现的功能是做一个loopback 测试,只要收到数据立刻发出去。

测试

实际测试下来,波特率设置为 256000bps ,按照 1ms 定时发送,发送:13227744byte 接收:13227744byte 没有丢失数据。

usb 转串口总是被大家认为是不稳定,原因就是在 usb 线拔掉后,串口也随之消失。原来操作系统为串口分配的内存等资源也没有被正确的释放,再将串口线插回去时,会出现打开串口失败!

下面提出操作 USB 转串口的正确方式:

  • 插上 usb 线,打开主机端串口;使用完毕后关闭串口,拔掉 usb 线
  • 插上 usb 线,打开主机端串口;拔掉 usb 线,关闭串口;插上 usb 线,打开串口

失败的方式:

  • 插上 usb 线,打开主机端串口;拔掉 usb 线,插上 usb 线;主机发送数据失败
  • 插上 usb 线,打开主机端串口;拔掉 usb 线,插上 usb 线;关闭串口,打开串口;主机发送数据失败

转载地址:http://hnzii.baihongyu.com/

你可能感兴趣的文章
使用Realsense D435i运行VINS-Fusion并建图
查看>>
gazebo似乎就是在装ROS的时候一起装了,装ROS的时候选择的是ros-melodic-desktop-full的话。
查看>>
React + TypeScript 实现泛型组件
查看>>
TypeScript 完全手册
查看>>
React Native之原理浅析
查看>>
Git操作清单
查看>>
基础算法
查看>>
前端面试
查看>>
React Hooks 异步操作踩坑记
查看>>
聊聊编码那些事,顺带实现base64
查看>>
TypeScript for React (Native) 进阶
查看>>
React 和 ReactNative 的渲染机制/ ReactNative 与原生之间的通信 / 如何自定义封装原生组件/RN中的多线程
查看>>
JavaScript实现DOM树的深度优先遍历和广度优先遍历
查看>>
webpack4 中的 React 全家桶配置指南,实战!
查看>>
react 设置代理(proxy) 实现跨域请求
查看>>
通过试题理解JavaScript
查看>>
webpack的面试题总结
查看>>
实践这一次,彻底搞懂浏览器缓存机制
查看>>
Koa2教程(常用中间件篇)
查看>>
React Hooks 完全指南
查看>>