STM32CubeMX USB CDC VCP?

Posted

技术标签:

【中文标题】STM32CubeMX USB CDC VCP?【英文标题】:STM32CubeMX USB CDC VCP? 【发布时间】:2016-02-06 13:18:56 【问题描述】:

我找到了大量的例子,但没有关于如何从 STM32MXCube 中“正确”地做到这一点。

如何从 STM32CubeMX 创建用于 USB CDC 虚拟 COM 端口通信的骨架代码(如果可能,STM32F4 Discovery)?

【问题讨论】:

【参考方案1】:

带有 CDC 作为 USB 设备的 Discovery F4 的 STM32CubeMX 项目应该可以开箱即用。假设您使用最新的 STM32CubeMX 和库:

启动STM32CubeMX 选择开发板 Discovery F4 仅启用外围 UBS_OTG_FS 设备(取消选中其他内容) 启用中间件 USB_Device Communication ..aka CDC

在时钟选项卡中检查时钟源是否为 HSE HCLK。它应在 48 MHz (USB) 中提供 168 MHz HLCK 和 48 MHz。检查任何地方都没有红色。

保存项目

生成代码(我使用的是 SW4STM32 工具链)

构建(您可能需要切换到内部 CDT 构建器与 GNU make)。

现在添加一些代码以通过 COM 端口发送数据,瞧,它应该可以工作了。

实际上,棘手的部分是在主机 USB 连接之前不要尝试进行任何“CDC”访问(尚未设置 CDC)

这是我为快速发射测试所做的:

在文件 usbd_cdc_if.c 中

uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)

    uint8_t result = USBD_OK;

    /* USER CODE BEGIN 7 */
    if (hUsbDevice_0 == NULL)
        return -1;

    USBD_CDC_SetTxBuffer(hUsbDevice_0, Buf, Len);
    result = USBD_CDC_TransmitPacket(hUsbDevice_0);
    /* USER CODE END 7 */

    return result;


static int8_t CDC_DeInit_FS(void)

    /* USER CODE BEGIN 4 */
    hUsbDevice_0 = NULL;
    return (USBD_OK);
    /* USER CODE END 4 */

在 main.c 文件中

/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
/* USER CODE END Includes */
....

/* USER CODE BEGIN WHILE */
while (1)

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    uint8_t HiMsg[] = "hello\r\n";
    CDC_Transmit_FS(HiMsg, strlen(HiMsg));
    HAL_Delay(200);

插入微型 USB (CN5) 后,CDC 数据将开始显示在主机终端上。

这行得通。我可以在终端上看到“hello”(您可能需要安装驱动程序,http://www.st.com/web/en/catalog/tools/PF257938)。

对于接收,它需要首先准备好,例如,首先在一个好的地方调用 USBD_CDC_ReceivePacket() 来启动它。为此,它可以是 CDC_Init_FS。

然后您可以在数据到达 CDC_Receive_FS 时对其进行处理,并从此处重新接收。

这对我有用。

static int8_t CDC_Receive_FS (uint8_t* Buf, uint32_t *Len)

    /* USER CODE BEGIN 6 */
    USBD_CDC_ReceivePacket(hUsbDevice_0);
    return (USBD_OK);
    /* USER CODE END 6 */


static int8_t CDC_Init_FS(void)

    hUsbDevice_0 = &hUsbDeviceFS;

    /* USER CODE BEGIN 3 */
    /* Set Application Buffers */
    USBD_CDC_SetTxBuffer(hUsbDevice_0, UserTxBufferFS, 0);
    USBD_CDC_SetRxBuffer(hUsbDevice_0, UserRxBufferFS);
    USBD_CDC_ReceivePacket(hUsbDevice_0);

    return (USBD_OK);
    /* USER CODE END 3 */

【讨论】:

第一个大 TNX! ,在我的 stm32f4Disc 设备管理器上执行此过程后显示 2 个虚拟 com 端口,我完全按照您所说的进行了操作,可能是什么问题? 为什么要切换构建(您可能需要切换到内部 cdt buidler vs gnu make )? @MichelSanches 感谢这个关于如何使用 CDC 驱动程序的非常简洁和简单的示例。也许我只是愚蠢,但这比所有 ST 文档的总和要有用得多。 很好的答案。对我来说棘手的是 STM32 虚拟 COM 端口驱动程序。通过运行VCP_V1.4.0_Setup 来安装它是不够的。自述文件包含安装后应执行的步骤。就像从安装目录运行 32 位 Windows 7 的 dpinst_x86.exe 一样。首先对我来说并不明显。 是的,我注意到了 Win 7 的设置问题,您找到了解决方法;)我确实注意到了它,也许它会得到修复......有一天?【参考方案2】:

STM32Cube 软件支持许多 STM32F4 Discovery 板,您没有说您使用的是哪一个,但我在使用 F401VCT MCU 的 Discovery 板上遇到了完全相同的问题。

安装 STM 虚拟 COM 端口驱动程序后,Windows 设备管理器显示 STMicroelectronics 虚拟 COM 端口,但带有黄色警告标记。终端应用程序 (PuTTY) 无法访问 COM 端口。

我最终发现 STMCube 程序的源代码输出存在问题。但是有一个简单的解决方法:

    打开一个新的STM32Cube项目并启用USB_OTG_FS作为设备 仅从 MiddleWares 中选择 CDC Virtual Port COM USB_Device 下拉菜单。 无需对任何 USB 设置进行其他更改即可生成源代码。 在文件 usbd_cdc_if.c 中,将 #define USB_HS_MAX_PACKET_SIZE512 更改为 256。 在文件 usbd_cdc.c 中,将 #define CDC_DATA_HS_MAX_PACKET_SIZE512 更改为 256

完成此操作后,黄色警告从设备管理器中消失,使用 PuTTY 时我可以在 CDC_Receive_FS 函数(在 usbd_cdc_if.c 文件中)接收数据。请注意,每次 STM32Cube 生成代码时,这些定义都会返回到它们的错误值,我还没有找到解决方法。

我希望这会有所帮助。

【讨论】:

这里要注意:很多STM32芯片甚至不支持HighSpeed。如果您使用的是全速芯片,USB_HS_MAX_PACKET_SIZE 必须等于 USB_FS_MAX_PACKET_SIZE,因为 CDC 代码有一个具有最大数据包大小的内部缓冲区。只需这样做,您就可以在这些 RAM 较差的设备中节省大量 RAM。【参考方案3】:

iChal's fix 努力去除黄色警告标记。

我想提一下,USB_HS_MAX_PACKET_SIZE 现在在 usbd_def.h 中,CDC_DATA_HS_MAX_PACKET_SIZE 在 usbd_cdc.h 中

我正在使用 STM32CubeMX v4.11.0 STM32Cube v1.0 和 STM32F401C-DISCO。

在进一步的工作中,我现在只需将堆大小设置为更大的值。 我将其设置为 0x600,因为我还启用了 FreeRTOS。我正在使用 IAR EWARM,所以在链接描述文件 stm32f401xc_flash.icf 中进行了更改。

【讨论】:

如果这可以帮助要求有一个下降的“最小堆大小”与 freertos +usb 堆栈是非 rtos 感知 malloc 的 cos 和 _sbrake 变得混乱,因为“任务 sp”不是共享堆/堆栈ram 因此它无法吐出/制动堆/堆栈。但是“malloc”(usb 堆栈)的使用无论如何都不是线程安全的。

以上是关于STM32CubeMX USB CDC VCP?的主要内容,如果未能解决你的问题,请参考以下文章

STM32 使用回调从 USB CDC VCP 检索数据

STM32 USB VCP(虚拟串口)

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

STM32F0 USB CDC_Init_FS() 和 CDC_Receive_FS() 使用 CubeMX

STM32CubeMX学习笔记(43)——USB接口使用(CDC虚拟串口)

STM32CubeMX学习笔记(43)——USB接口使用(CDC虚拟串口)