【解決方案】STM32F103C8單片機運行CubeMX生成的CDC虛擬串口的程序,設備能枚舉成功但不能啓動的解決辦法

這是因爲USB的描述符出了問題。

Win10系統下不需要裝任何驅動就能使用USB虛擬串口,但更低版本的系統比如Win7則必須要安裝ST官方提供的VCP驅動:STM32 Virtual COM Port Driver(STSW-STM32102)

在Windows 7下,usbd_desc.c中的設備描述符USBD_DeviceDesc的bDeviceClass和bDeviceSubClass可以爲0,但USBD_VID必須爲0x0483,USBD_PID必須爲0x5740,否則無法匹配上安裝的VCP驅動,導致設備無法啓動,如下圖所示。

而在Windows 10下,由於採用的是Windows自帶的虛擬串口的驅動程序,所以USBD_VID和USBD_PID可以爲任意值,但是bDeviceClass和bDeviceSubClass都必須爲0x02,不能爲0,否則將無法匹配上Windows自帶的驅動,導致設備無法啓動,如下圖所示。

所以,綜上所述,USBD_VID應該爲0x0483,USBD_PID應該爲0x5740,bDeviceClass和bDeviceSubClass都應該爲0x02。

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USBD_VID                      0x0483  // 由於Win7下虛擬串口必須要裝ST驅動, 所以產品ID和設備ID必須是這兩個值, 否則不能匹配上驅動
#define USBD_PID                      0x5740
#define USBD_LANGID_STRING            0x0409  // 英語
#define USBD_MANUFACTURER_STRING      "Hello Manufacturer" /* Add your manufacturer string */
#define USBD_PRODUCT_HS_STRING        "Hello Product HS" /* Add your product High Speed string */
#define USBD_PRODUCT_FS_STRING        "Hello Product FS" /* Add your product Full Speed string */
#define USBD_CONFIGURATION_HS_STRING  "Hello Configuration HS" /* Add your configuration High Speed string */
#define USBD_INTERFACE_HS_STRING      "Hello Interface HS" /* Add your Interface High Speed string */
#define USBD_CONFIGURATION_FS_STRING  "Hello Configuration FS" /* Add your configuration Full Speed string */
#define USBD_INTERFACE_FS_STRING      "Hello Interface FS" /* Add your Interface Full Speed string */
__ALIGN_BEGIN   uint8_t USBD_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END =
{
  0x12,                       /* bLength */
  USB_DESC_TYPE_DEVICE,       /* bDescriptorType */
  0x00,                       /* bcdUSB */
  0x02,
  0x02,                       /* bDeviceClass */ // 這兩個必須爲0x02, 否則Win10下無法啓動設備
  0x02,                       /* bDeviceSubClass */
  0x00,                       /* bDeviceProtocol */
  USB_MAX_EP0_SIZE,           /* bMaxPacketSize */
  LOBYTE(USBD_VID),           /* idVendor */
  HIBYTE(USBD_VID),           /* idVendor */
  LOBYTE(USBD_PID),           /* idVendor */
  HIBYTE(USBD_PID),           /* idVendor */
  0x00,                       /* bcdDevice rel. 2.00 */
  0x02,
  USBD_IDX_MFC_STR,           /* Index of manufacturer string */
  USBD_IDX_PRODUCT_STR,       /* Index of product string */
  USBD_IDX_SERIAL_STR,        /* Index of serial number string */
  USBD_MAX_NUM_CONFIGURATION  /* bNumConfigurations */
}; /* USB_DeviceDescriptor */

另外,如果usbd_conf.h裏面的內存分配函數選擇的是malloc和free,那就需要保證USBD_CDC_Init裏面的USBD_malloc能夠成功分配內存,否則將無法啓動設備。

/* Memory management macros */
#define USBD_malloc               malloc
#define USBD_free                 free

由於USBD_CDC_HandleTypeDef裏面的data成員大小爲512字節,所以在啓動文件startup_stm32f103xb.s中要將Heap_Size改大,默認的0x200(512字節)肯定是不行的。

 

CubeMX生成完工程後還要檢查USB的中斷函數是否存在,是否打開了USB中斷。有的時候CubeMX生成的工程中不含USB中斷的代碼,導致USB設備插上去無法識別。

// 打開USB中斷
HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);
/* USB中斷處理函數 */
void USB_LP_CAN1_RX0_IRQHandler(void)
{
  HAL_PCD_IRQHandler(&hpcd);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章