creepphp 该用户从未签到html
版主测试 最后登陆大数据 2018-10-19优化
|
电梯直达ui 楼主 发表于 2016-12-3 18:36:34 | 只看该做者 |只看大图 spa
本帖最后由 creep 于 2017-10-17 14:31 编辑
STM32F769 Discovery (STM32官网)板载有一个 USB OTG HS 接口和一个USB 高速PHY USB3320C-EZK,两者配合能够实现高速的虚拟串口和PC或者其余设备进行通讯,下面咱们就简单的看下高速的VCP的移植和通讯速度,并和其余的板子上的全速VCP进行对比。
一、硬件 USB OTG HS 的外部PHY为USB3320C,和stm32769硬件接口以下,
USB3320C的时钟使用板载的24M晶振,并输出60MHZ的时钟给USB 高速模块,这个全速USB设备的48MHZ时钟有些区别。
移植的时候须要根据STM32F769 Discovery 的原理图确认具体是哪些引脚和USB3320C进行通讯。
二、软件移植
ST官方提供了完善的USB库,移植很是简单,只须要根据具体的硬件设置要初始化的引脚便可,此处必定要注意必须根据原理图链接进行初始化化,不一样的ST开发板的接法可能不一样:
- /* Configure USB HS GPIOs */
- __HAL_RCC_GPIOA_CLK_ENABLE();
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOC_CLK_ENABLE();
- __HAL_RCC_GPIOH_CLK_ENABLE();
- __HAL_RCC_GPIOI_CLK_ENABLE();
-
-
- /* CLK */
- GPIO_InitStruct.Pin = GPIO_PIN_5;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* D0 */
- GPIO_InitStruct.Pin = GPIO_PIN_3;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* D1 D2 D3 D4 D5 D6 D7 */
- GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 |\
- GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
- /* STP */
- GPIO_InitStruct.Pin = GPIO_PIN_0;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-
- /* NXT */
- GPIO_InitStruct.Pin = GPIO_PIN_4;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
-
- /* DIR */
- GPIO_InitStruct.Pin = GPIO_PIN_11;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
- HAL_GPIO_Init(GPIOI, &GPIO_InitStruct)
复制代码而后在编译器的预处理定义中选择高速外设:
最后在main函数中初始化USB便可:
- int main(void)
- {
- uint8_t TestBuff[512];
- uint16_t t;
- /* Enable the CPU Cache */
- CPU_CACHE_Enable();
- HAL_Init();
- /* Configure the system clock to 216 MHz */
- SystemClock_Config();
-
- USART1_Init();
- for(t = 0;t < 512;t++)TestBuff[t] = t;
- /* Init Device Library */
- USBD_Init(&USBD_Device, &VCP_Desc, 0);
-
- /* Add Supported Class */
- USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS);
-
- /* Add CDC Interface Class */
- USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);
-
- /* Start Device Process */
- USBD_Start(&USBD_Device);
- /* Infinite loop */
- while (1)
- {
- USB2PC(TestBuff,512);
- }
- }
复制代码下载程序到板子后应该就能够在电脑设备管理器看到虚拟串口
若是是第一次使用VCP就要安装官方的驱动,有的电脑可能不是正版系统会致使安装驱动失败,解决办法能够参考这个帖子: 虚拟串口驱动安装失败的解决方法
基本上常见的串口驱动问题均可以解决,若是驱动安装成功后还提示设备有问题,能够尝试将代码的堆栈修改大一些试下。
三、数据传输
全速的USB VCP一次最多能够发送64个字节,高速的USB VCP 一次能够最多发送512个字节,若是一次发送整个数据包的数据,须要再发送一个数据个数为0的数据包,不然上位机可能无法接收数据。 USB发送数据主要是调用下面的函数:
- //发送数据PC
- uint8_t UsbSendData(uint8_t *pbuff,uint16_t buffsize)
- {
- uint16_t retry = 0;
- USBD_HandleTypeDef *pdev = &USBD_Device;
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
-
- hcdc->TxBuffer = pbuff;
- hcdc->TxLength = buffsize;
-
- if(pdev->pClassData != NULL)
- {
- if(hcdc->TxState == 0)
- {
- /* Tx Transfer in progress */
- hcdc->TxState = 1;
-
- /* Transmit next packet */
- USBD_LL_Transmit(pdev,
- CDC_IN_EP,
- hcdc->TxBuffer,
- hcdc->TxLength);
-
- }
- else
- {
- return USBD_BUSY;
- }
- }
- //等待发送结束
- while(hcdc->TxState == 1)
- {
- retry++;
- if(retry == 0xfff0)
- {
- return USBD_FAIL;
- }
- }
- return USBD_OK;
- }
复制代码根据上面USB发送数据包的要求,咱们使用下面的函数来调用上面的函数来发送任意大小的数据,这个函数会自动在发送最大数据包后再发送一个空的数据包。USB_PACK_SIZE根据USB模式可能为64或者512
- //可发送任意字节的数据到PC端
- void USB2PC(uint8_t *str,uint16_t len)
- {
- uint16_t j = 0;
- if(len < USB_PACK_SIZE)
- {
- UsbSendData(str,len);
- }
- else
- {
- for (j = 0;j < len/USB_PACK_SIZE;j++)
- {
- UsbSendData((str+USB_PACK_SIZE*j),USB_PACK_SIZE);
- }
- UsbSendData((str+USB_PACK_SIZE*j),len%USB_PACK_SIZE);
- }
- }
复制代码为了测试发送的最大速度,我在main函数中循环调用发送函数一次发送512字节,发送内容为0X00-0XFF. 由于发送数据量比较大,有些串口助手可能会卡死,我使用SecureCRT 进行接收.接收数据以下,由于SecureCRT显示的ASCII,因此有些显示是乱码,可是数据是对的,
使用监控软件看到发送数据以下,能够每一个数据包为512字节,每次发送的内容为0x00-0xFF.数据没有出错。
具体的发送速度以下,屡次测试能够看到软件计算的结果有些不一样
为了对比咱们测试下STM32F746 Discovery上全速的USB发送速度,
- int main(void)
- {
- uint8_t TestBuff[64];
- uint16_t t;
- CPU_CACHE_Enable();
- HAL_Init();
- SystemClock_Config();
- LED_Init();
- /* Init Device Library */
- USBD_Init(&USBD_Device, &VCP_Desc, 0);
-
- /* Add Supported Class */
- USBD_RegisterClass(&USBD_Device, USBD_CDC_CLASS);
-
- /* Add CDC Interface Class */
- USBD_CDC_RegisterInterface(&USBD_Device, &USBD_CDC_fops);
-
- /* Start Device Process */
- USBD_Start(&USBD_Device);
- for(t = 0;t < 64;t++)TestBuff[t] = t;
- while(1)
- {
- USB2PC(TestBuff,64);
- }
- }
复制代码
SecureCRT看到的数据
监控软件检测到的数据,数据包大小为64字节
检测到发送速度
全速USB的理论最大速度为12Mbps,高速USB的为480Mpbs,明显上面测的数据和理论的最大数度有些差距。不一样的检测软件可能测试获得的数据不一样,经过对比能够看到高速USB VCP和全速USB VCP仍是有些速度提高的。测试代码使用keil5.20编译,代码没有进行任何优化。USB库是2016的比较新的版本。感兴趣的同窗可使用优化代码或者其余编译器编译代码试下是否是速度有所提高。
我在测试高速USB VCP的时候由于发送数据量较大,在我电脑上win10安装以后的首次蓝屏,赶忙拍照留念,微软早晚药丸。
测试代码; STM32F746 Discovery VCP-FS.rar (951.89 KB, 下载次数: 146) STM32F769 Discovery VCP-HS.rar (894.67 KB, 下载次数: 136) 参考文档 USB3200.pdf (970.61 KB, 下载次数: 93) Discovery kit with STM32F769NI MCU.pdf (2.1 MB, 下载次数: 120)
推荐阅读: STM32 USB CDC 虚拟多串口 |
STM32F769 评分
查看所有评分 |