RT-Thread论坛
直播中

孙奕

8年用户 976经验值
私信 关注
[问答]

CherryUSB +STM32F103C8 example usb cdc device不识别是怎么回事?

请问下使用STM32F103 blue pill 板子
1.按照文档教程 及 视频教程 使用https://github.com/CherryUSB/cherryusb_stm32 中stm32f103c8t6 配置cdc,使用cubeMX 配置生成xxx_msp.c
为什么 放开 CONFIG_USBDEV_SETUP_LOG_PRINT 发现 usb 中断 一直未能进入

  • ____usbd_event_ep0_setup_complete_handler ;


回帖(2)

潘凌

2025-9-10 16:47:53
正常,f1 所有系列需要上拉电阻,这是常识,百度一下 stm32f103 usb 上拉电阻 你就知道
举报

洪茗苞

2025-9-12 18:19:53

针对CherryUSB + STM32F103C8 USB CDC设备不识别的问题(特别是USB中断未进入____usbd_event_ep0_setup_complete_handler),以下是逐步排查方案和解决方法:




关键问题点总结



  1. USB中断未触发 → Setup包处理函数未被调用  

  2. CubeMX配置兼容性 → CherryUSB依赖底层寄存器级操作,CubeMX生成的HAL库可能冲突  

  3. 描述符/时钟/引脚配置错误 → 设备无法响应主机枚举




一、中断问题排查(核心步骤)


1. 确认中断向量表对齐



  • 问题:STM32F103C8T6 Flash起始地址为0x08000000,但中断向量表需对齐到512字节(0x200)

  • 解决:在system_stm32f1xx.c中修改向量表偏移:
     SCB->VTOR = 0x08000000 | 0x200; // 对齐到0x08000200


2. 检查中断服务函数



  • 确保在stm32f1xx_it.c中注册了正确的USB中断处理函数:
     #include "cherryusb.h"
    void USB_LP_CAN1_RX0_IRQHandler(void) {
         usbd_irq_handler(0); // CherryUSB的中断入口
    }

  • 移除CubeMX生成的HAL_PCD_IRQHandler()调用(与CherryUSB冲突)。


3. 启用USB中断



  • usbd_configure()函数中启用中断:
     __HAL_RCC_USB_CLK_ENABLE();       // 使能USB时钟
    HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);




二、CubeMX配置调整


1. 时钟树配置



  • USB必须使用48MHz时钟(由PLL提供):

    • HSE(8MHz)→ PLL倍频到72MHz → USB预分频器1.5(PLL_USB_DIV_1.5)→ 输出48MHz  

    • SystemClock_Config()中确认:
      RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // 8MHz * 9 = 72MHz
      RCC_OTGFSCLKConfig(RCC_OTGFSCLKSource_PLLVCO_Div3);   // 72MHz / 1.5 = 48MHz



2. 引脚配置



  • 检查PA11 (USB_DM) 和PA12 (USB_DP):

    • 在CubeMX中开启USB Device模式,无需开启VBus检测(配置VBUS_SensingDisable)。



3. 禁用HAL USB初始化



  • 移除CubeMX生成的USB初始化代码(CherryUSB直接操作寄存器):

    • 删除MX_USB_DEVICE_Init()调用  

    • 保留CubeMX生成的HAL_PCD_MspInit()中的时钟和引脚配置(但删除HAL中断相关代码)。





三、CherryUSB配置修正


1. 描述符检查



  • 确保usbd_descriptor.c中设备描述符正确:
     const uint8_t usbd_device_descriptor[0x12] = {
         0x12,        // bLength
         DESC_TYPE_DEVICE,  // bDescriptorType
         0x0200,      // bcdUSB (USB 2.0)
         CLASS_CDC,    // bDeviceClass
         0x00,        // bDeviceSubClass
         0x00,        // bDeviceProtocol
         0x40,        // bMaxPacketSize0 (64 bytes)
         0x0416,      // idVendor (Custom VID)
         0x0483,      // idProduct (Custom PID)
         ...
    };


2. 启用调试日志



  • usb_config.h中开启日志:
     #define CONFIG_USBDEV_DESC_LOG
    #define CONFIG_USBDEV_SETUP_LOG_PRINT
    #define CONFIG_USBDEV_REQUEST_LOG_PRINT

  • 检查串口日志输出(如Setup包接收情况)。


3. 端点缓存配置



  • CherryUSB需配置端点缓存地址(避免与HAL库冲突):
     // 在 usbd_core.c 中手动初始化端点缓存
    usbd_ep_buffer_config(EP_IN_ADDR(0x81), 64); // CDC端点1 IN
    usbd_ep_buffer_config(EP_OUT_ADDR(0x01), 64); // CDC端点1 OUT




四、硬件检查




  1. USB D+ 上拉电阻

    Blue Pill板需确认1.5kΩ上拉电阻是否连接到PA12(USB_DP)。若无,需在代码中启用内部上拉:


    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP; // 启用内部上拉
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);



  2. 供电问题:  



    • 使用外接5V电源或确认USB线支持数据传输(非充电线)。






五、完整代码流程(main.c示例)


#include "cherryusb.h"
#include "usb_cdc.h"

int main(void) {
    // 1. 初始化系统和时钟(CubeMX生成)
    HAL_Init();
    SystemClock_Config();

    // 2. 初始化USB引脚(CubeMX生成)
    MX_GPIO_Init(); // 保留PA11/PA12配置

    // 3. 初始化CherryUSB核心
    usbd_init();
    usbd_cdc_acm_init();
    usbd_connect(1); // 连接USB

    while (1) {
        usbd_polling_loop(); // CherryUSB主循环
    }
}



调试步骤



  1. 测量信号:用示波器检查PA12(USB_DP)是否有1.5V的复位信号(主机复位设备)。

  2. 查看寄存器:调试时检查USB寄存器状态:
    uint16_t istatus = USB->ISTR; // ISTR寄存器值
    uint16_t cntr = USB->CNTR;    // 控制寄存器

  3. 日志分析:通过串口输出CONFIG_USBDEV_SETUP_LOG_PRINT的日志,确认Setup包是否被接收。




常见陷阱



  • CubeMX代码残留:删除所有USB_DEVICE文件夹和usbd_conf.c/h文件  

  • 中断优先级:确保USB中断优先级高于其他中断(如SysTick)  

  • 枚举超时:主机可能在枚举失败后停止通信,尝试更换USB端口或重启主机  


通过以上步骤,重点解决中断触发问题并确保CubeMX配置与CherryUSB兼容性,设备应能正确识别。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分