1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > USB VCP虚拟串口通讯详细配置步骤(STM32H732)

USB VCP虚拟串口通讯详细配置步骤(STM32H732)

时间:2019-06-29 01:58:06

相关推荐

USB VCP虚拟串口通讯详细配置步骤(STM32H732)

USB VCP虚拟串口通讯详细配置步骤(STM32H732)

一、软件版本二、CodeMX配置1、使能外部高速时钟。2、开启USB外设,选择USB Device功能,速度为默认全速USB设备12Mbps,使用默认配置。3、配置中间层使能CDC(VPC),参数依然全默认。4、时钟配置,选用外部HSE时钟源,将USB时钟配置为48MHz。5、修改Heap Size和Stack Size大小,太小导致串口识别不到或者识别错误出现黄色感叹号。6、生成Keil工程,编译运行代码。7、打开设备管理器,复位单片机,识别到虚拟串口。三、软件配置1、单片机向PC发送,在main.c中声明发送字符串和长度。2、PC向单片机发送,在usbd_cdc_if.c修改函数,实现接收回传。3、添加USB_printf打印函数,在usbd_cdc_if.c添加函数,方便直接输出字符串。四、速度测试

一、软件版本

1、单片机型号:STM32H743IIT6;正点原子-阿波罗版

2、Keil-MDK:V5.32

3、CubeMX:6.7.0

4、HAL:STM32Cube FW_H7 V1.11.0

5、参考文章:

1.STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯

2.STM32CubeIDE 简单配置USB虚拟串口 并实现printf

3.STM32Cube配置USB虚拟串口发送与接收回传

4.STM32USB开发备忘之CDC_VCP实验

二、CodeMX配置

1、使能外部高速时钟。

2、开启USB外设,选择USB Device功能,速度为默认全速USB设备12Mbps,使用默认配置。

3、配置中间层使能CDC(VPC),参数依然全默认。

4、时钟配置,选用外部HSE时钟源,将USB时钟配置为48MHz。

5、修改Heap Size和Stack Size大小,太小导致串口识别不到或者识别错误出现黄色感叹号。

6、生成Keil工程,编译运行代码。

7、打开设备管理器,复位单片机,识别到虚拟串口。

三、软件配置

主要修改usbd_cdc_if.c和main.c,会使用这四个函数,就可以用单片机与PC进行USB基本通信:

CDC_Control_FS()

来自主机请求的回调函数;CDC控制命令处理,列举了主机有可能向设备发送的一些命令。没有具体的处理过程,需要用户自己编写。其中包括串口参数的设置,要做串口转USB通信的话需要修改这里。只是为了用USB与PC通信则不用管这里。每个命令具体的意思需要查询CDC类手册。

CDC_Receive_FS()

接收数据回调函数;Buf为接收缓存。这个缓存实际上就是CDC_Init_FS()中设置的UserRxBufferFS[]数组。这个全局数组的定义在usbd_cdc_if.c文件中。Len为接收到数据的长度。这个变量不是全局的,需要用户声明变量把这个传出去。

CDC_Transmit_FS()

用来发送数据;

CDC_TransmitCplt_FS()

发送完成回调函数;

1、单片机向PC发送,在main.c中声明发送字符串和长度。

#include "usbd_core.h"#include "usbd_cdc.h"#include "usbd_cdc_if.h"char USB_TxBuf[32];uint16_t len;/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){len=sprintf(USB_TxBuf,"Hello GJtech!\r\n");CDC_Transmit_FS((uint8_t*)USB_TxBuf,len);HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}

2、PC向单片机发送,在usbd_cdc_if.c修改函数,实现接收回传。

接收函数在usbd_cdc_if.h中并没有给出,而是在usbd_cdc_if.c中以static关键字给出的,这个函数其实是在USB接收时自动进入中断并调用的,可以直接在其中将接收缓冲区的内容做处理或转存。

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len){CDC_Transmit_FS(Buf,*Len);USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return (USBD_OK);}

3、添加USB_printf打印函数,在usbd_cdc_if.c添加函数,方便直接输出字符串。

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */#include <stdarg.h>void usb_printf(const char *format, ...){va_list args;uint32_t length;va_start(args, format);length = vsnprintf((char *)UserTxBufferFS, APP_TX_DATA_SIZE, (char *)format, args);va_end(args);CDC_Transmit_FS(UserTxBufferFS, length);}/* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */

四、速度测试

在此正点原子单片机上,编写Python代码测试速度,可得到单片机发送数据速度为868.352K Byte/s(6.9M bps),接收速度为804.864K Byte/s(6.4M bps)。

因为相比硬件串口而言,USB虚拟的串口速度可以变得非常快,图形化的串口工具已经无法用来测速了,所以用python写了个脚本进行测试,测试脚本如下:

#!/usr/bin/env python3# -*- coding: utf-8 -*-from typing import Counterimport serialimport serial.tools.list_portsimport timeimport datetimeprint('正在搜索串口……')port_list = list(serial.ports())print('发现串口:')for i in range(0, len(port_list)):print(port_list[i])print('')port = input('请输入串口号,并按回车确认: ')print('')ser = serial.Serial(port, 22333, timeout=5)run = Truecount = 0starttime = int(round(time.time() * 1000))print(datetime.datetime.now().strftime('%H:%M:%S.%f') + ':开始测试单片机向上位机发送数据……')ser.write('S'.encode('utf-8'))while (run):ser.read(2048) # 接收来自单片机的数据count += 1currenttime = int(round(time.time() * 1000))run = False if (currenttime - starttime) >= 1000 else Trueser.write('E'.encode('utf-8'))print(datetime.datetime.now().strftime('%H:%M:%S.%f') + ':结束测试,速度约为 ' + str(count * 2048 / 1000) + 'K Byte/s' +'='+ str(count * 2048 / 1000*8) + 'K bps\n')sendbuf = bytes(2048)run = Truecount = 0starttime = int(round(time.time() * 1000))print(datetime.datetime.now().strftime('%H:%M:%S.%f') + ':开始测试单片机接收上位机的数据……')while (run):count += ser.write(sendbuf) # 向单片机发送数据currenttime = int(round(time.time() * 1000))run = False if (currenttime - starttime) >= 1000 else Trueprint(datetime.datetime.now().strftime('%H:%M:%S.%f') + ':结束测试,速度约为 ' + str(count / 1000) + 'K Byte/s' +'=' +str(count / 1000*8) + 'K bps\n')ser.close()exit()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。