本文共 9536 字,大约阅读时间需要 31 分钟。
芯片: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 * ** * 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
© COPYRIGHT 2015 STMicroelectronics
实现的功能是做一个loopback
测试,只要收到数据立刻发出去。
实际测试下来,波特率设置为 256000bps
,按照 1ms
定时发送,发送:13227744byte
接收:13227744byte
没有丢失数据。
usb
转串口总是被大家认为是不稳定,原因就是在 usb
线拔掉后,串口也随之消失。原来操作系统为串口分配的内存等资源也没有被正确的释放,再将串口线插回去时,会出现打开串口失败!
下面提出操作 USB
转串口的正确方式:
usb
线,打开主机端串口;使用完毕后关闭串口,拔掉 usb
线usb
线,打开主机端串口;拔掉 usb
线,关闭串口;插上 usb
线,打开串口失败的方式:
usb
线,打开主机端串口;拔掉 usb
线,插上 usb
线;主机发送数据失败usb
线,打开主机端串口;拔掉 usb
线,插上 usb
线;关闭串口,打开串口;主机发送数据失败转载地址:http://hnzii.baihongyu.com/