[STM32F4] STM32F429 USB 主机

[复制链接]
52|3
east森林 发表于 2026-11-4 08:31 | 显示全部楼层 |阅读模式

我要为 STM32F429 探索板开发 USB 全速主机驱动。到目前为止,无论是 MSC 类、HID 类还是厂商类都无法完成枚举,卡住了。

USB 端口是有供电的。我用 CubeMX 生成代码,用 Keil MDK-ARM uVision 5 编译烧录。最初,`usb_core.c`中`USBH_Process()`的主状态机一直卡在 HOST_IDLE。我通过在`USBH_Start()`里添加调用`USBH_LL_Connect()`修复了这一点 ,这个函数似乎能将设备状态置为已连接。我还修改了 HOST_DEV_WAIT_FOR_ATTACHMENT 状态,让它进入 HOST_DEV_ATTACHED,否则会一直卡住。

现在状态机卡在 HOST_DEV_ATTACHED,而且从更底层代码返回的状态全是 USBH_BUSY。

下面是 CubeMX 生成的时钟初始化代码。



void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;


__PWR_CLK_ENABLE();


__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);


RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 336;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 7;

HAL_RCC_OscConfig(&RCC_OscInitStruct);


RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1

|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);


HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);


HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}


这个问题已经快让我把头发拔光了,我只想让设备完成枚举VID、PID 等。

powerantone 发表于 2026-11-4 10:22 | 显示全部楼层
手动调用 USBH_LL_Connect() 来绕过 HOST_IDLE 属于掩盖问题,并非修复问题。底层硬件中断没有正常触发连接检测,说明 VBUS sensing 或 GPIO 配置大概率是错的,强行改状态机只会让后面卡得更深。
cr315 发表于 2026-11-4 10:24 | 显示全部楼层
检查 USB_OTG_GCCFG 寄存器里的 VBUS sensing 位。STM32F4 作为主机时,如果没正确配置 NOVBUSSENS 或 VBUSBSEN,控制器根本不会认为总线上有有效设备,后面所有枚举请求都发不出去。
classroom 发表于 2026-11-4 10:58 | 显示全部楼层
HOST_DEV_ATTACHED 之后全是 USBH_BUSY,通常意味着主机发了复位或取描述符的请求但设备没回应。这时候应该用逻辑分析仪抓 D+ / D- 波形,看复位时序到底有没有发出去,而不是继续在代码里猜。
duo点 发表于 2026-11-4 11:30 | 显示全部楼层
USBH_BUSY 从最底层一路返回上来,大概率是控制传输根本没有完成。先确认 HAL_HCD_HC_GetURBState 的返回值是什么,如果是 URB_TXERR 或一直 URB_NOTREADY,说明 token 包发出去后连 NAK 都没收到,物理层链路就不通。
flycamelaaa 发表于 2026-11-4 12:10 | 显示全部楼层
你贴的时钟配置里 PLLQ = 7,配合 PLLN = 336 和 PLLM = 8,算出来 USB 时钟是 48 MHz,这部分是对的。但如果 HSE 实际不是 8 MHz(比如板子上焊的是 25 MHz 晶振),USB 时钟就偏了,全速枚举必然失败,先确认 HSE_VALUE 宏和实际晶振一致。
jcky001 发表于 2026-11-4 12:48 | 显示全部楼层
探索板上 PA9 是 VBUS 控制引脚。如果你用的是 CubeMX 生成的 Host 工程,检查 HAL_HCD_MspInit 里有没有把 PA9 配成输出并拉高。VBUS 没供上或者供晚了,设备根本不会拉 D+ 上拉电阻,主机自然检测不到连接。
WhisperingTrees 发表于 2026-11-4 12:50 | 显示全部楼层
检查一下USB中断优先级配置,可能是优先级太低导致中断处理不及时,可以适当提高USB中断的优先级。
onlycook 发表于 2026-11-4 13:26 | 显示全部楼层
建议先把 USBH_Process() 里的 HOST_DEV_ATTACHED 分支加上串口打印,把每次进入枚举后 USBH_HandleEnum 返回的具体值打出来。USBH_BUSY 一直循环和偶尔返回一次 USBH_FAIL 是完全不同的故障方向。
powerantone 发表于 2026-11-4 14:15 | 显示全部楼层
有人说 ST 的 USB Host 库对某些设备兼容性不好,但 VID / PID 都读不到的情况基本跟类驱动无关,问题一定在 USBH_CtlReq 这一层。先把控制传输的 URB 状态机跟一遍,确认 SETUP 包有没有真的从 FIFO 推出去。
probedog 发表于 2026-11-4 16:55 | 显示全部楼层
如果 D+ / D- 接反了,主机侧完全不会有反应,状态机会停在等待连接或者反复复位。虽然听起来很蠢,但探索板的 USB 座子如果用过转接板或者自己飞过线,先用万用表量一下 PA11 / PA12 和座子引脚的通断及对应关系,能省很多时间。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

79

主题

909

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部