STM32 USB转串口分析

4 篇文章 0 订阅

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=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%PRVDR%
CatalogFile=stmcdc.cat
DriverVer=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.inf
CopyFiles=FakeModemCopyFileSection
AddReg=DriverInstall.NT.AddReg

[DriverInstall.NT.AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"

[DriverInstall.NT.Services]
AddService=usbser, 0x00000002, DriverServiceInst

[DriverServiceInst]
DisplayName=%SERVICE%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary= %12%\usbser.sys
LoadOrderGroup = 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 软件自动生成一份下位机程序,测试下来还是和以前移植的程序现象一样

解决

网上搜索原因:stm32的usb虚拟串口驱动win7系统64位和32位不能正常安装的解决办法!stm32 virtual comport win7(终极解决办法) ,原来是 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
  *
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
  *
  * 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<Len; ++i) {
     g_RxByte = Buf[i];
     VCP_DataTx();
  }

  return USBD_OK;
}

/**
  * @brief  VCP_COMConfig
  *         Configure the COM Port with default values or values received from host.
  * @param  Conf: can be DEFAULT_CONFIG to set the default configuration or OTHER_CONFIG
  *         to set a configuration received from the host.
  * @retval None.
  */
static uint16_t VCP_COMConfig(uint8_t Conf)
{
  return USBD_OK;
}

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

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

测试

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

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

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

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

失败的方式:

  • 插上 usb 线,打开主机端串口;拔掉 usb 线,插上 usb 线;主机发送数据失败
  • 插上 usb 线,打开主机端串口;拔掉 usb 线,插上 usb 线;关闭串口,打开串口;主机发送数据失败
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Amlogic USB Burning Tool(阿莫逻辑USB刷机工具)是一种专门用于刷写安卓系列设备固件的软件工具。V2.2.0版本是该工具的一个版本。 Amlogic USB Burning Tool提供了一个简单而功能强大的界面来帮助用户刷写Amlogic芯片设备的固件。它适用于多种设备,如智能电视盒、智能电视和其他安卓设备。使用这个工具,用户可以轻松地安装、升级或恢复设备的固件。 该工具的主要特点包括: 1. 一键刷写固件:用户只需将设备与电脑连接,选择要刷写的固件文件,然后点击“开始”按钮即可开始刷写过程。 2. 支持多种固件格式:Amlogic USB Burning Tool支持多种常见的固件格式,如IMG、BIN等,用户只需选择合适的文件格式即可。 3. 强大的刷写功能:它可以刷写完整固件、区域固件或仅刷写特定分区。用户可以根据需要选择合适的刷写方式。 4. 实时反馈和错误提示:该工具在刷写过程中提供实时的刷写进度和反馈信息,以及错误提示,帮助用户更好地操作设备。 Amlogic USB Burning Tool的V2.2.0版本可能提供一些新的功能或改进。虽然我无法提供该版本具体的更新内容,但通常这些版本更新可能包括性能优化、修复bug、增加兼容性以及改进用户界面等方面的改善。 总的来说,Amlogic USB Burning Tool V2.2.0是一款方便易用且功能强大的刷机工具,适用于Amlogic芯片系列设备的固件刷写和升级。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值