坑人的官方固件库...


# 软硬件版本

  • Windows 1909 或 2004 Preview
  • STM32F407VET6
  • STM32CubeMX 5.4.0 / 5.6.0 / 5.6.1
  • USB 库 v1.0_Cube

# 症状描述

  • Windows 可检测到虚拟串口,无感叹号(时序设置正确)
  • Windows API 中,
    • CreateFileA 正常
    • SetCommState 失败, GetLastError 返回 56
  • PuTTY 无法连接串口,TeraTerm 正常

# 产生原因

单片机无法响应行编码 (Line Coding) 信息

# 解决方法

  1. 在 usbd_cdc_if.c 中添加如下代码:

    /*******************************************************************************/
    /* Line Coding Structure                                                       */
    /*-----------------------------------------------------------------------------*/
    /* Offset | Field       | Size | Value  | Description                          */
    /* 0      | dwDTERate   |   4  | Number |Data terminal rate, in bits per second*/
    /* 4      | bCharFormat |   1  | Number | Stop bits                            */
    /*                                        0 - 1 Stop bit                       */
    /*                                        1 - 1.5 Stop bits                    */
    /*                                        2 - 2 Stop bits                      */
    /* 5      | bParityType |  1   | Number | Parity                               */
    /*                                        0 - None                             */
    /*                                        1 - Odd                              */
    /*                                        2 - Even                             */
    /*                                        3 - Mark                             */
    /*                                        4 - Space                            */
    /* 6      | bDataBits  |   1   | Number Data bits (5, 6, 7, 8 or 16).          */
    /*******************************************************************************/
    static uint8_t lineCoding[7] // 115200bps, 1stop, no parity, 8bit
        = { 0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08 };
  2. 调整 CDC_Control_FS 函数,添加如下两行:

    static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
      /* USER CODE BEGIN 5 */
      switch(cmd) {
      ...
        case CDC_SET_LINE_CODING:
          memcpy(lineCoding, pbuf, sizeof(lineCoding));   // This line
        break;
        case CDC_GET_LINE_CODING:
          memcpy(pbuf, lineCoding, sizeof(lineCoding));   // This line
        break;
        ...
    }

# 参考链接

# 后记 & 牢骚

据说这两个地方原来是有的,但是 ST 官方把它们删掉了...

我再也不相信官方库了 /(ㄒ o ㄒ)/~~