搜索
查看: 28415|回复: 60

[STM32F769-DISC] 【F769IDISCOVERY评测】高速USB VCP和全速USB VCP 速度对比

  [复制链接]

该用户从未签到

60

主题

2111

帖子

31

蝴蝶豆

版主

最后登录
2023-6-21
发表于 2016-12-3 18:36:34 | 显示全部楼层 |阅读模式
本帖最后由 creep 于 2017-10-17 14:31 编辑

              STM32F769 Discovery STM32官网板载有一个  USB OTG HS 接口和一个USB 高速PHY USB3320C-EZK,二者配合可以实现高速的虚拟串口和PC或者其他设备进行通信,下面我们就简单的看下高速的VCP的移植和通信速度,并和其他的板子上的全速VCP进行对比。

2016-12-03_172548.png



1、硬件
   USB OTG HS 的外部PHY为USB3320C,和stm32769硬件接口如下,

2016-12-03_173551.png

USB3320C的时钟使用板载的24M晶振,并输出60MHZ的时钟给USB 高速模块,这个全速USB设备的48MHZ时钟有些区别。

2016-12-03_173350.png

移植的时候需要根据STM32F769 Discovery 的原理图确认具体是哪些引脚和USB3320C进行通信。

2、软件移植

    ST官方提供了完善的USB库,移植非常简单,只需要根据具体的硬件设置要初始化的引脚即可,此处一定要注意必须根据原理图连接进行初始化化,不同的ST开发板的接法可能不同:
  1. /* Configure USB HS GPIOs */
  2.     __HAL_RCC_GPIOA_CLK_ENABLE();
  3.     __HAL_RCC_GPIOB_CLK_ENABLE();
  4.     __HAL_RCC_GPIOC_CLK_ENABLE();
  5.     __HAL_RCC_GPIOH_CLK_ENABLE();
  6.                 __HAL_RCC_GPIOI_CLK_ENABLE();

  7.    
  8.     /* CLK */
  9.     GPIO_InitStruct.Pin = GPIO_PIN_5;
  10.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  11.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  12.     GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  13.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  14.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  15.    
  16.     /* D0 */
  17.     GPIO_InitStruct.Pin = GPIO_PIN_3;
  18.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  19.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  20.     GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  21.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  22.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  23.    
  24.     /* D1 D2 D3 D4 D5 D6 D7 */
  25.     GPIO_InitStruct.Pin = GPIO_PIN_0  | GPIO_PIN_1  | GPIO_PIN_5 |\
  26.       GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
  27.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  28.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  29.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  30.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  31.    
  32.     /* STP */
  33.     GPIO_InitStruct.Pin = GPIO_PIN_0;
  34.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  35.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  36.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  37.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  38.    
  39.     /* NXT */
  40.     GPIO_InitStruct.Pin = GPIO_PIN_4;
  41.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  42.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  43.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  44.     HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  45.    
  46.     /* DIR */
  47.     GPIO_InitStruct.Pin = GPIO_PIN_11;
  48.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  49.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  50.     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
  51.     HAL_GPIO_Init(GPIOI, &GPIO_InitStruct)
复制代码
然后在编译器的预处理定义中选择高速外设:

2016-12-03_174440.png

最后在main函数中初始化USB即可:
  1. int main(void)
  2. {
  3.                 uint8_t TestBuff[512];
  4.                 uint16_t t;
  5.                 /* Enable the CPU Cache */
  6.                 CPU_CACHE_Enable();
  7.                 HAL_Init();
  8.                 /* Configure the system clock to 216 MHz */
  9.                 SystemClock_Config();

  10.                 USART1_Init();
  11.                 for(t = 0;t < 512;t++)TestBuff[t] = t;        
  12.                 /* Init Device Library */
  13.                 USBD_Init(&USBD_Device, &VCP_Desc, 0);

  14.                 /* Add Supported Class */
  15.                 USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS);

  16.                 /* Add CDC Interface Class */
  17.                 USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);

  18.                 /* Start Device Process */
  19.                 USBD_Start(&USBD_Device);
  20.   /* Infinite loop */
  21.                 while (1)
  22.                 {
  23.                         USB2PC(TestBuff,512);
  24.                 }
  25. }
复制代码
下载程序到板子后应该就可以在电脑设备管理器看到虚拟串口

2016-12-03_174828.png

如果是第一次使用VCP就要安装官方的驱动,有的电脑可能不是正版系统会导致安装驱动失败,解决办法可以参考这个帖子:
虚拟串口驱动安装失败的解决方法

基本上常见的串口驱动问题都可以解决,如果驱动安装成功后还提示设备有问题,可以尝试将代码的堆栈修改大一些试下。


  3、数据传输

    全速的USB VCP一次最多可以发送64个字节,高速的USB VCP 一次可以最多发送512个字节,如果一次发送整个数据包的数据,需要再发送一个数据个数为0的数据包,否则上位机可能没法接收数据。   USB发送数据主要是调用下面的函数:
  1. //发送数据PC
  2. uint8_t UsbSendData(uint8_t *pbuff,uint16_t buffsize)
  3. {
  4.         uint16_t retry = 0;
  5.         USBD_HandleTypeDef   *pdev = &USBD_Device;
  6.         USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
  7.   
  8.   hcdc->TxBuffer = pbuff;
  9.   hcdc->TxLength = buffsize;  
  10.         
  11.   if(pdev->pClassData != NULL)
  12.   {
  13.     if(hcdc->TxState == 0)
  14.     {
  15.       /* Tx Transfer in progress */
  16.       hcdc->TxState = 1;
  17.       
  18.       /* Transmit next packet */
  19.       USBD_LL_Transmit(pdev,
  20.                        CDC_IN_EP,
  21.                        hcdc->TxBuffer,
  22.                        hcdc->TxLength);               
  23.       
  24.     }
  25.     else
  26.     {
  27.       return USBD_BUSY;
  28.     }
  29.   }
  30.         //等待发送结束        
  31.         while(hcdc->TxState == 1)
  32.         {
  33.                 retry++;
  34.                 if(retry == 0xfff0)
  35.                 {
  36.                         return USBD_FAIL;
  37.                 }               
  38.         }
  39.         return USBD_OK;
  40. }
复制代码
根据上面USB发送数据包的要求,我们使用下面的函数来调用上面的函数来发送任意大小的数据,这个函数会自动在发送最大数据包后再发送一个空的数据包。USB_PACK_SIZE根据USB模式可能为64或者512
  1. //可发送任意字节的数据到PC端
  2. void USB2PC(uint8_t *str,uint16_t len)
  3. {
  4.         uint16_t j = 0;
  5.         if(len < USB_PACK_SIZE)
  6.         {
  7.                 UsbSendData(str,len);
  8.         }
  9.         else
  10.         {
  11.                 for (j = 0;j < len/USB_PACK_SIZE;j++)
  12.                 {
  13.                         UsbSendData((str+USB_PACK_SIZE*j),USB_PACK_SIZE);
  14.                 }
  15.                 UsbSendData((str+USB_PACK_SIZE*j),len%USB_PACK_SIZE);
  16.         }        
  17. }
复制代码
为了测试发送的最大速度,我在main函数中循环调用发送函数一次发送512字节,发送内容为0X00-0XFF.
因为发送数据量比较大,有些串口助手可能会卡死,我使用SecureCRT 进行接收.接收数据如下,因为SecureCRT显示的ASCII,所以有些显示是乱码,但是数据是对的,
11.png

使用监控软件看到发送数据如下,可以每个数据包为512字节,每次发送的内容为0x00-0xFF.数据没有出错。

2016-12-03_121047.png

具体的发送速度如下,多次测试可以看到软件计算的结果有些不同

123.png

456.png

779.png

为了对比我们测试下STM32F746 Discovery上全速的USB发送速度,
  1. int main(void)
  2. {
  3.                 uint8_t TestBuff[64];
  4.                 uint16_t t;
  5.     CPU_CACHE_Enable();
  6.     HAL_Init();
  7.                 SystemClock_Config();
  8.     LED_Init();
  9.           /* Init Device Library */
  10.                 USBD_Init(&USBD_Device, &VCP_Desc, 0);
  11.                
  12.                 /* Add Supported Class */
  13.                 USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS);
  14.                
  15.                 /* Add CDC Interface Class */
  16.                 USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);
  17.                
  18.                 /* Start Device Process */
  19.                 USBD_Start(&USBD_Device);
  20.                 for(t = 0;t < 64;t++)TestBuff[t] = t;
  21.     while(1)
  22.     {
  23.                         USB2PC(TestBuff,64);
  24.                 }
  25. }
复制代码


SecureCRT看到的数据

FS-VCP.png

监控软件检测到的数据,数据包大小为64字节

FS-VCP0.png

检测到发送速度

FS-VCP1.png

       全速USB的理论最大速度为12Mbps,高速USB的为480Mpbs,明显上面测的数据和理论的最大数度有些差距。不同的检测软件可能测试得到的数据不同,通过对比可以看到高速USB VCP和全速USB VCP还是有些速度提升的。测试代码使用keil5.20编译,代码没有进行任何优化。USB库是2016的比较新的版本。感兴趣的同学可以使用优化代码或者其他编译器编译代码试下是不是速度有所提升。

    我在测试高速USB VCP的时候因为发送数据量较大,在我电脑上win10安装之后的首次蓝屏,赶紧拍照留念,微软迟早药丸。

76B236E9BF8A73E26DC747D142776ACE.png

测试代码;
STM32F746 Discovery VCP-FS.rar (951.89 KB, 下载次数: 289)

评分

参与人数 5ST金币 +47 收起 理由
liuzhijun + 1
kylongmu + 20 很给力!
xmshao + 5 赞一个!
zero99 + 20
wofei1314 + 1 赞一个!

查看全部评分

回复

使用道具 举报

该用户从未签到

6

主题

468

帖子

0

蝴蝶豆

金牌会员

最后登录
2019-12-28
发表于 2016-12-3 19:31:39 | 显示全部楼层
好贴必须顶起 win10被你弄死机了
回复 支持 反对

使用道具 举报

该用户从未签到

33

主题

1276

帖子

0

蝴蝶豆

论坛元老

最后登录
2020-12-19
发表于 2016-12-3 20:09:11 | 显示全部楼层
跟着大神学USB
回复 支持 反对

使用道具 举报

该用户从未签到

64

主题

809

帖子

23

蝴蝶豆

实习版主

最后登录
2021-4-25
发表于 2016-12-3 20:34:06 | 显示全部楼层
厉害
回复

使用道具 举报

该用户从未签到

47

主题

3456

帖子

30

蝴蝶豆

版主

最后登录
2022-12-25
发表于 2016-12-3 20:49:06 | 显示全部楼层
顶起,学习了。。。
回复 支持 反对

使用道具 举报

该用户从未签到

47

主题

1683

帖子

7

蝴蝶豆

论坛元老

最后登录
2022-4-9
发表于 2016-12-3 20:57:13 | 显示全部楼层
你拿USB VCP虚拟串口的速度和全速/高速USB的速度对比,这。。。
回复 支持 反对

使用道具 举报

该用户从未签到

60

主题

2111

帖子

31

蝴蝶豆

版主

最后登录
2023-6-21
 楼主| 发表于 2016-12-3 22:02:21 | 显示全部楼层
moyanming2013 发表于 2016-12-3 20:57
你拿USB VCP虚拟串口的速度和全速/高速USB的速度对比,这。。。

大神,让您见笑了。
我就是顺便对比下。。。
给有需要的人或者想知道差别的同学一个基本的参考。
回复 支持 反对

使用道具 举报

该用户从未签到

60

主题

2111

帖子

31

蝴蝶豆

版主

最后登录
2023-6-21
 楼主| 发表于 2016-12-3 22:03:43 | 显示全部楼层
霹雳之火 发表于 2016-12-3 19:31
好贴必须顶起 win10被你弄死机了

微软大法好,升级了win10后,好多年的旧笔记本又满血复活了。
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

3

帖子

0

蝴蝶豆

初级会员

最后登录
2019-11-26
发表于 2016-12-4 09:06:57 来自手机 | 显示全部楼层
vcp速度上不去是因为你的usb没有做双缓冲,做一下就好了。不过开启stm32 IN端点的双缓冲时序还是蛮复杂的,并且官方没有任何参考历程
回复 支持 反对

使用道具 举报

该用户从未签到

29

主题

1285

帖子

59

蝴蝶豆

论坛元老

最后登录
2021-6-27
发表于 2016-12-4 09:37:58 | 显示全部楼层
没有蓝屏不微软
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-25 16:05 , Processed in 1.225570 second(s), 47 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表