用户工具

站点工具


usb_cdc实验_高速数据传输
银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
版本 日期 作者 修改内容
V1.0 2020-07-04 gingko 初次建立

实验十五:USB_CDC实验——高速数据传输

一、 实验目的与意义

  1. 了解STM32 USB结构。
  2. 了解STM32 USB特征。
  3. 掌握USB的使用方法。
  4. 掌握USB CDC类。
  5. 掌握KEIL MDK 集成开发环境使用方法。

二、 实验设备及平台

  1. iCore4 双核心板点击购买
  2. JLINK(或相同功能)仿真器点击购买
  3. Micro USB线缆。
  4. Keil MDK 开发平台。
  5. 装有WIN XP(及更高版本)系统的计算机。

三、 实验原理

1、USB CDC简介

  • USB的CDC类是USB通信设备类(Communication Device Class)的简称。CDC类是USB组织定义的一类专门给各种通信设备(电信通信设备和中速网络通信设备)使用的USB子类。根据CDC类所针对通信设备的不同,CDC类又被分成以下不同的模型:USB传统纯电话业务(POTS)模型,USBISDN模型和USB网络模型,其中USB传统纯电话业务模型又可分为直线控制模型(Direct Line Control Model)、抽象模型、电话模型。虚拟串口就属于USB传统纯电话业务模型下的抽象控制模型。
  • 如下图所示,USB CDC类的通信部分主要包含三部分:枚举过程、虚拟串口操作和数据通信。其中虚拟串口操作部分并不一定强制需要,因为若跳过这些虚拟串口的操作,实际上USB依然是可以通信的,这也就是为什么下图中,在操作虚拟串口之前会有两条数据通信的数据。之所以会有虚拟串口操作,主要是我们通常使用PC作为Host端,在PC端使用一个串口工具来与其进行通信,PC端的对应驱动将其虚拟成一个普通串口,这样一来,可以方便PC端软件通过操作串口的方式来与其进行通信,但实际上,Host端与Device端物理上是通过USB总线来进行通信的,与串口没有关系,这一虚拟化过程,起决定性作用的是对应驱动,包含如何将每一条具体的虚拟串口操作对应到实际上的USB操作。需要注意的是,Host端与Device端的USB通信速率并不受所谓的串口波特率影响,它就是标准的USB2.0全速(12Mbps)速度,实际速率取决于总线的实际使用率、驱动访问USB外设有效速率(两边)以及外部环境对通信本身造成的干扰率等因素组成。

2、CDC类软件框架

  • 如上图所示,黄色USB Device Core部分为USB设备库文件,属于中间件,它为USB协议栈的核心源文件,一般不需要修改:
  • USB Device Core中,Log/debug为打印/调试开关;
  • core为USB设备核心;
  • USB request中定义了枚举过程中各种标准请求的处理;
  • I/O request为底层针对USB通信接口的封装。
  • 黄色USB Device Class部分为USB类文件,也属于中间件,USB设备库,目前ST DEMO中支持的类有HID, Customer HID, CDC, MSC, DFU, Audio, ST提供了这些类的源码框架,其他的Class或者是复合设备需要自己根据实际需求情况进行扩展或定制。如果用户需求只是需要一个标准类,比如CDC通信,那么最好就使用现成的代码,不需要做任何修改就可以实现这个CDC类通信的功能。
  • 蓝色USB Device HAL Driver为HAL库部分,是对USB外设接口的封装,属于底层驱动,不需要修改,它分为PCD和LL Driver,PCD处于LL Driver之上。
  • 洋红色USB Device Configuration为USB配置封装,位于USB底层HAL层驱动与中间件USB协议栈之间,一方面向上层(USB设备库)提供各种操作调用接口,另一方面,向底层USB驱动提供各种回调接口。正是由于它的存在,使得USB协议栈(USB设备库)与底层硬件完全分离,从而使USB设备库具有更加兼容所有STM32的通用性。USB Device Configuration为开放给用户的源文件,用户可以根据自己的某些特殊需要进行修改,也可以使用默认的源文件,假如没有任何特殊要求的话,我们使用默认即可。
  • Application为应用层,USB Device Class有可能将自己对应该的操作接口封装在一个操作数据结构中,由应用来具体实现这些操作,在系统初始化时,由应用将已经定义好的操作接口注册到对应的USB类中,比如usbd_cdc_if, 就这样,使得应用层的应用代码与属于中间件层的USB协议栈分离。同时,USB协议栈会将一些字符串描述符放到APP中,当USB初始化时将这些已经定义好的字符串通过指针初始化到USB协议栈中,以便后续需要时获取。

3、原理图

  • 本实验通过调用STM32的HAL库来实现STM32的USB 设备通信,由于STM32芯片不带高速PHY,在这里我们用STM32F767和USB3300链接的方式来实现数据的高速传输,通过编写的测试软件测试出传输速度。原理图如下:

四、 实验程序

1、主函数

int main(void)
{
    int i;
    static unsigned char data_number = 0;
    system_clock.initialize();//系统时钟初始化
    led.initialize();         //LED初始化
 
    USBD_Init(&USB_OTG_dev,
        USB_OTG_HS_CORE_ID,
        &USR_desc,
        &USBD_CDC_cb,
        &USR_cb);
    while(State==0);
    LED_GREEN_ON;
    while(1)
    {
        //接受数据并处理
        if(USB_ReceivedCount > 0){
            LED_RED_ON; 
            USB_ReceivedCount = 0;
            //重复发送次数
            data_number = USB_Rx_Buffer[0];
            //发送图片
            do{
                USB_StatusDataSended = 0;
                DCD_EP_Tx(&USB_OTG_dev,CDC_IN_EP,gImage_flower,sizeof(gImage_flower));
                while(USB_StatusDataSended == 0){
                    for(i = 0;i < 10000;i++);
                }
                data_number--;
            }while(data_number > 0);
            LED_RED_OFF;
        }
    }    
}
 

2、USB初始化

/* 初始化设备堆栈并加载类驱动程序 */
void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
               USB_OTG_CORE_ID_TypeDef coreID,
               USBD_DEVICE *pDevice,                  
               USBD_Class_cb_TypeDef *class_cb, 
               USBD_Usr_cb_TypeDef *usr_cb)
  {
  /* 硬件初始化 */
  USB_OTG_BSP_Init(pdev);  
  USBD_DeInit(pdev);
  /*寄存器类和用户回调 */
  pdev->dev.class_cb = class_cb;
  pdev->dev.usr_cb = usr_cb;  
  pdev->dev.usr_device = pDevice;    
  /* 设置USB OTG核心参数 */
  DCD_Init(pdev , coreID);
  /* 在初始化调用用户回调时 */
  pdev->dev.usr_cb->Init();
  /*使能中断*/
  USB_OTG_BSP_EnableInterrupt(pdev);
}

3、发送数据

  • 主函数中通过调用此函数来发送照片数据。
/**
* @brief通过USB传输数据
* @param pdev:设备实例
* @param ep_addr:端点地址
* @param pbuf:指向Tx缓冲区的指针
* @param buf_len:数据长度
* @retval:状态
*/
uint32_t  DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev,
                     uint8_t   ep_addr,
                     uint8_t   *pbuf,
                     uint32_t   buf_len)
{
  USB_OTG_EP *ep;
  ep = &pdev->dev.in_ep[ep_addr & 0x7F];
  /* 设置并开始传输 */
  ep->is_in = 1;
  ep->num = ep_addr & 0x7F;  
  ep->xfer_buff = pbuf;
  ep->dma_addr = (uint32_t)pbuf;  
  ep->xfer_count = 0;
  ep->xfer_len  = buf_len;
  if ( ep->num == 0 )
  {
    USB_OTG_EP0StartXfer(pdev , ep);
  }
  else
  {
    USB_OTG_EPStartXfer(pdev, ep );
  }
  return 0;
}

五、 实验步骤

  1. 把仿真器与iCore4的SWD调试口相连(直接相连或者通过转接器相连);
  2. 将跳线帽插在USB OTG。
  3. 把iCore4(USB OTG)通过Micro USB线与计算机相连,为iCore4供电;
  4. 安装USB CDC驱动,驱动安装方法参考例程包中安装方法文档。
  5. 打开Keil MDK开发环境,并打开本实验工程;
  6. 烧写程序到iCore4上;
  7. 打开上位机软件usb.exe,点击打开,测试按钮即可测试。(如果该软件没能正常启动,则重新安装驱动)
  8. 也可以进入Debug模式,单步运行或设置断点验证程序逻辑。

六、 实验现象

  • 绿色LED灯点亮,结果如下图所示:

usb_cdc实验_高速数据传输.txt · 最后更改: 2022/03/22 10:20 由 sean