1)实验平台:正点原子STM32mini开发板
2)摘自《正点原子STM32 不完全手册(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子
第三十八章 USB 虚拟串口实验
STM32F103 系列芯片都自带了 USB,不过 STM32F103 的 USB 都只能用来做设备,而
不能用作主机。既便如此,对于一般应用来说已经足够了。本章,我们将向大家介绍如何在
ALIENTEK MiniSTM32 开发板上利用 STM32 自生的 USB 功能实现一个虚拟串口。本章分
为如下几个部分:
38.1 USB 简介
38.2 硬件设计
38.3 软件设计
38.4 下载验证
38.1 USB 简介
USB ,是英文 Universal Serial BUS(通用串行总线)的缩写,而其中文简称为“通串线,是
一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。
USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、
Microsoft 等多家公司联合提出的。
USB 发展到现在已经有 USB1.0/1.1/2.0/3.0 等多个版本。目前用的最多的就是 USB1.1 和
USB2.0,USB3.0 目前已经开始普及。STM32F103 自带的 USB 符合 USB2.0 规范。
标准 USB 共四根线组成,除 VCC/GND 外,另外为 D+,D-; 这两根数据线采用的是差分电
压的方式进行数据传输的。在 USB 主机上,D-和 D+都是接了 15K 的电阻到低的,所以在没有
设备接入的时候,D+、D-均是低电平。而在 USB 设备中,如果是高速设备,则会在 D+上接一
个 1.5K 的电阻到 VCC,而如果是低速设备,则会在 D-上接一个 1.5K 的电阻到 VCC。这样当
设备接入主机的时候,主机就可以判断是否有设备接入,并能判断设备是高速设备还是低速设
备。接下来,我们简单介绍一下 STM32 的 USB 控制器。
STM32F103 的 MCU 自带 USB 从控制器,符合 USB 规范的通信连接;PC 主机和微控制器
之间的数据传输是通过共享一专用的数据缓冲区来完成的,该数据缓冲区能被 USB 外设直接访
问。这块专用数据缓冲区的大小由所使用的端点数目和每个端点最大的数据分组大小所决定,
每个端点最大可使用 512 字节缓冲区(专用的 512 字节,和 CAN 共用),最多可用于 16 个单
向或 8 个双向端点。USB 模块同 PC 主机通信,根据 USB 规范实现令牌分组的检测,数据发送
/接收的处理,和握手分组的处理。整个传输的格式由硬件完成,其中包括 CRC 的生成和校验。
每个端点都有一个缓冲区描述块,描述该端点使用的缓冲区地址、大小和需要传输的字节
数。当 USB 模块识别出一个有效的功能/端点的令牌分组时,(如果需要传输数据并且端点已配
置)随之发生相关的数据传输。USB 模块通过一个内部的 16 位寄存器实现端口与专用缓冲区的
数据交换。在所有的数据传输完成后,如果需要,则根据传输的方向,发送或接收适当的握手
分组。在数据传输结束时,USB 模块将触发与端点相关的中断,通过读状态寄存器和/或者利用
不同的中断来处理。
USB 的中断映射单元:将可能产生中断的 USB 事件映射到三个不同的 NVIC 请求线上:
1、USB 低优先级中断(通道 20):可由所有 USB 事件触发(正确传输,USB 复位等)。固件
在处理中断前应当首先确定中断源。
2、USB 高优先级中断(通道 19):仅能由同步和双缓冲批量传输的正确传输事件触发,目
的是保证最大的传输速率。
3、USB 唤醒中断(通道 42):由 USB 挂起模式的唤醒事件触发。
USB 设备框图如图 38.1.1 所示:
STM32F1 USB 的其他介绍,请大家参考《STM32 中文参考手册》第 21 章内容,我们这里
就不再详细介绍了。
要正常使用 STM32F1 的 USB,就得编写 USB 驱动,而整个 USB 通信的详细过程是很复
杂的,本书篇幅有限,不可能在这里详细介绍,有兴趣的朋友可以去看看电脑圈圈的《圈圈教
你玩 USB》这本书,该书对 USB 通信有详细讲解。如果要我们自己编写 USB 驱动,那是一件
相当困难的事情,尤其对于从没了解过 USB 的人来说,基本上不花个一两年时间学习,是没法
搞定的。不过,ST 提供了我们一套完整的 USB 驱动库,通过这个库,我们可以很方便的实现
我们所要的功能,而不需要详细了解 USB 的整个驱动,大大缩短了我们的开发时间和精力。
ST提 供的USB驱 动库 , 可 以 在:https://www.stmicroelectronics.com.cn/zh/microcontrollers-microprocessors/stm32f103.html#tools-so
ftware 这里下载。不过,我们已经帮大家下载到开发板光盘:8,STM32 参考资料1,
STM32CubeF1 固件包。打开固件包 en.stm32cubef1STM32Cube_FW_F1_V1.8.0MiddlewaresST
目录下可以找到 USB 驱动库,如图 38.1.2 所示:
USB 相关资料在目录: 资料盘(A 盘) 8,STM32 参考资料2,STM32 USB 学习资料,专
门讲解 USB 库的原理和使用。有了这些资料对我们了解 STM32F103 的 USB 会有不少帮助,尤
其在不懂的时候,看看 ST 的例程,会有意想不到的收获。本实验的 USB 部分就是移植 ST 的
Virtual_COM_Port 例程相关部分而来,完成一个 USB 虚拟串口的功能。
38.2 硬件设计
本章实验功能简介:本实验利用 STM32 自带的 USB 功能,连接电脑 USB,虚拟出一个 USB
串口,实现电脑和开发板的数据通信。本例程功能完全同实验 3(串口实验),只不过串口变
成了 STM32 的 USB 虚拟串口。当 USB 连接电脑,开发板将通过 USB 和电脑建立连接虚拟出
一个串口(注意:需要先安装:光盘6,软件资料1,软件STM32 USB 虚拟串口驱动
VCP_V1.4.0_Setup.exe 这个驱动软件),USB 和电脑连接成功后,DS1 常亮。
在找到虚拟串口后,即可打开串口调试助手,实现同实验 3 一样的功能,即:STM32 通
过 USB 虚拟串口和上位机对话,STM32 在收到上位机发过来的字符串(以回车换行结束)后,
原原本本的返回给上位机。下载后,DS0 闪烁,提示程序在运行,同时每隔一定时间,通过
USB 虚拟串口输出一段信息到电脑。
所要用到的硬件资源如下:
1) 指示灯 DS0 、DS1
2) 串口
3) TFTLCD 模块
4) USB 接口
前面 3 部分,在之前的实例中都介绍过了,我们在此就不介绍了。接下来看看我们电脑 USB
与 STM32 的 USB 连接口。ALIENTEK MiniSTM32 采用的是 5PIN 的 MiniUSB 接头,用来和
STM32 的 USB 相连接,连接电路如图 38.2.1 所示:
从上图可以看出,USB 是直接连接到 STM32 上面的,所以硬件上不需要什么变动。
38.3 软件设计
本章,我们在:实验 13 TFTLCD 显示实验的基础上修改,代码移植自 ST 官方例程
,我打开该例程即可知道 USB 相关的代码有哪些,如图 38.3.1 所示:
首先,在本章例程(即实验 13 TFTLCD 显示实验)的工程文件夹下面,新建 USB 文件夹,并拷贝官方USB驱 动 库 相 关 代 码 到 该 文 件 夹 下 , 即 拷 贝 :
en.stm32cubef1STM32Cube_FW_F1_V1.8.0MiddlewaresST 文件夹下的 STM32_USB_Device_Library 文件夹到该文件夹下面。
然后,在 USB 文件夹下,新建 CONFIG 文件夹存放 Virtual COM 实现相关代码,最后
CONFIG 文件夹下的文件如图 38.3.2 所示:
之后,根据 ST 官方 JoyStickMouse例程,在我们本章例程的基础上新建分组添加相关代码,
具体细节,这里就不详细介绍了,添加好之后,如图 38.3.3 所示:
USB 相关代码,请大家直接参考例程。注意,本例程有些是经过修改了的,并非完全
照搬官方例程。最后在 main.c 里面,我们修改 main 函数如下:
extern USBD_HandleTypeDef hUsbDeviceFS;
extern PCD_HandleTypeDef hpcd_USB_FS;
int main(void)
{
u16 t;
u16 len;
u16 times=0;
u8 usbstatus=0;
HAL_Init();
//初始化 HAL 库
Stm32_Clock_Init(RCC_PLL_MUL9); //设置时钟,72M,9 倍频 8Mhzx9 = 72Mhz
delay_init(72);
//初始化延时函数
uart_init(115200);
//初始化串口
LED_Init();
//初始化 LED
LCD_Init();
//初始化 LCD FSMC 接口
POINT_COLOR=RED;
//设置字体为红色
LCD_ShowString(30,50,200,16,16,"Mini STM32F103 ^_^");
LCD_ShowString(30,70,200,16,16,"USB Virtual USART TEST");
LCD_ShowString(30,90,200,16,16,"JASONZHANG@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2019/11/16");
LCD_ShowString(30,130,200,16,16,"USB Connecting...");//提示 USB 开始连接
USB_Reset();//USB 断开再重连
MX_USB_DEVICE_Init();//USB 设备初始化
LCD_ShowString(30,150,200,16,16,"USB inited...");
while(1)
{
if(usbstatus!=USB_GetStatus())
{
usbstatus = USB_GetStatus();//记录新的状态
if(usbstatus==USBD_STATE_CONFIGURED)
{
POINT_COLOR=BLUE;
LCD_ShowString(30,170,200,16,16,"USB Connected ");
//提示 USB 连接成功
LED1=0;//DS1 亮
} else
{
POINT_COLOR=RED;
LCD_ShowString(30,170,200,16,16,"USB disConnected ");//提示 USB 断开
LED1=1;//DS1 灭
}
}
if(USB_USART_RX_STA&0x8000)
{
len=USB_USART_RX_STA&0x3FFF;//得到此次接收到的数据长度
USB_Printf(" 您发送的消息长度为:%d",len);
for(t=0; t
{
USB_USART_SendData(&USB_USART_RX_BUF[t]);//字符发送
}
USB_Printf("");//插入换行
USB_USART_RX_STA=0;
} else
{
times++;
if(times%5000==0)
{
USB_Printf("Mini STM32 开发板 USB 虚拟串口实验");
USB_Printf("正点原子@ALIENTEK");
}
if(times%200==0) USB_Printf("请输入数据,以回车键结束");
if(times%30==0)LED0=!LED0;//闪烁 LED,提示系统正在运行.
delay_ms(10);
}
}
}
软件设计部分,就给大家介绍到这里。
38.4 下载验证
本例程的测试,需要在电脑上先安装 ST 提供的 USB 虚拟串口驱动软件,该软件路径:光
盘→6,软件资料→1,软件→STM32 USB 虚拟串口驱动→ VCP_V1.4.0_Setup.exe,双击安装即
可。
然后,在代码编译成功之后,我们下载代码到 Mini STM32 V3.0 上,然后将 USB 数据线,
插入 USB 口,连接电脑和开发板(注意:不是插 USB_232 端口!),此时电脑会提示找到新硬
件,并自动安装驱动。不过,如果自动安装不成功(有惊叹号),如图 38.4.1 所示:
此时,我们可手动选择驱动(以 WIN7 为例),进行安装,在如图 48.4.1 所示的条目上面,
右键→更新驱动程序软件→浏览计算机以查找驱动程序软件→浏览,选择 STM32 虚拟串口的驱
动的路径为:C:Program Files (x86)STMicroelectronicsSoftwareVirtual comport driverWIN7,然
后点击下一步,即可完成安装。安装完成后,可以看到设备管理器里面多出了一个 STM32 的
虚拟串口,如图 38.4.2 所示:
图 38.4.2 ,STM32 通过 USB 虚拟的串口,被电脑识别了,端口号为:COM5(可变),字
符串名字为:STMicroelectronics Virtual COM Port(固定)。此时,开发板的 DS1 常亮,同时,
开发板的 LCD 显示 USB Connected,如图 38.4.3 所示:
然后我们打开 XCOM,选择 COM5(需根据自己的电脑识别到的串口号选择),并打开串
口(注意:波特率可以随意设置),就可以进行测试了,如图 38.4.4 所示:
可以看到,我们的串口调试助手,收到了来自 STM32 开发板的数据,同时,按发送按钮(串口助手必须勾选:发送新行),也可以收到电脑发送给 STM32 的数据(原样返回),说明我们的实验是成功的。实验现象同第八章完全一样。至此,USB 虚拟串口实验就完成了,通过本实验,我们就可以利用 STM32 的 USB,直接和电脑进行数据互传了,具有广泛的应用前景。