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

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

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

【问题讨论】:

    标签: usb stm32 stm32f4discovery


    【解决方案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 程序的源代码输出存在问题。但是有一个简单的解决方法:

    1. 打开一个新的STM32Cube项目并启用USB_OTG_FS作为设备 仅从 MiddleWares 中选择 CDC Virtual Port COM USB_Device 下拉菜单。
    2. 无需对任何 USB 设置进行其他更改即可生成源代码。
    3. 在文件 usbd_cdc_if.c 中,将 #define USB_HS_MAX_PACKET_SIZE512 更改为 256
    4. 在文件 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 堆栈)的使用无论如何都不是线程安全的。
    猜你喜欢
    • 1970-01-01
    • 2016-09-03
    • 2017-09-05
    • 2017-02-27
    • 2017-03-28
    • 2016-10-29
    • 2020-08-09
    • 2018-09-24
    • 2021-11-23
    相关资源
    最近更新 更多