版本
软件版本
-
Cube:5.4.0
-
HAL:STM32Cube FW_F4 V1.24.2
-
Keil:V5.25.2.0
硬件版本
- STM32F407ZGT6
目标
实现USB虚拟串口功能。
重点
- HeapStack的配置
- 读操作
CDC_Receive_FS
的改写 - 项目工程源码链接
过程
Cube配置
RCC配置
使能外部和内部时钟。
SYS配置
使用SWD调试,时间基准源采用SysTick
。
USB_OTG_FS配置
该配置选择Device_Only
模式,其他配置默认即可。
USB_DEVICE配置
Class For FS - CDC,其他配置默认即可。
时钟配置
使用系统方案,需要注意的点:
- 选用外部HSE时钟源;
- 将USB时钟配置为48MHz。
如下图所示:
生成Keil工程
生成工程时,需要将内置的Heap_Stack
扩大,否则在USB虚拟串口时,电脑会出现黄色感叹号的情况1,本工程配置如下:
软件配置
在生成的工程中,主要通过配置usbd_cdc_if.c
文件实现对串口的操作,常用操作有读写操作,如下:
读操作
CDC_Receive_FS
- 原型:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
变量 | 类型 | 说明 |
---|---|---|
Buf | uint8_t* | 接收到的数据源指针 |
Len | uint32_t * | 接收到的数据长度 |
该方法为静态方法,由系统底层进行调用,用户不需要直接调用该方法。用户只需要在这个函数中添加代码,将数据和数据长度复制到自己的接收缓存中即可2。
- 例子
/* USER CODE BEGIN PRIVATE_VARIABLES */
extern unsigned char rxBuff[2048]; // 外部接收缓存
extern uint32_t wIdx; // 写指针
/* USER CODE END PRIVATE_VARIABLES */
// 其他代码 ...
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
// 将数据循环写入全局变量缓存中
for(int i=0;i<Len[0];i++)
{
rxBuff[((wIdx++)&0x7FF)] = Buf[i];
}
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
写操作
CDC_Transmit_FS
- 原型:
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
变量 | 类型 | 说明 |
---|---|---|
Buf | uint8_t* | 发送的数据源指针 |
Len | uint32_t * | 发送的数据长度 |
该方法在头文件中对外有生命,所以使用过程中直接调用即可。
- 例子:
// 其他代码 ...
CDC_Transmit_FS((unsigned char *)txBuff, sprintf(txBuff, "dlt - %10d\r\n", dlt));
// 其他代码 ...
总结
通过USB虚拟串口功能,可以节省硬件的设计,同时USB接口还可以设计为HID设备,所以选用USB设备可以极大程度节省开发硬件成本,但是会增加软件开发成本,不过总的来说优大于劣。