针对STM32H750中同时使用USB HS Host(通过USB3300)和DCMI接口时USB中断停止工作的问题,以下是系统性解决方案:
1. 检查DMA冲突(最可能的原因)
- 问题分析:
DCMI默认使用DMA2,而USB可能隐式使用DMA(尤其是端点FIFO传输时)。DMA通道或流资源冲突会导致总线仲裁失败。
- 解决步骤:
- 为USB显式分配DMA通道:
在USB初始化代码中,确保为USB端点分配独立的DMA流(非DMA2),例如使用BDMA(专为低速外设设计):
// 在USB初始化前配置BDMA
HAL_RCC_BDMA_CLK_ENABLE();
hpcd.Init.dma_enable = 1;
hpcd.Init.phy_itface = USB_OTG_HS_ULPI_PHY;
hpcd.Init.Sof_enable = 1;
hpcd.Init.low_power_enable = 0;
hpcd.Init.dma_burst_length = USB_DMA_BURST_INCR4;
hpcd.hInstance = USB_OTG_HS;
hpcd.Instance = USB_OTG_HS;
HAL_PCD_Init(&hpcd);
- 检查DCMI的DMA流分配:
确保DCMI使用的DMA2流与USB或其他外设无重叠(参考STM32H750手册):
__HAL_RCC_DMA2_CLK_ENABLE();
hdma.Instance = DMA2_Stream1; // 避免使用Stream0(可能被DCMI默认占用)
HAL_DMA_Init(&hdma);
- 验证仲裁器配置:
在SystemClock_Config()中确保DMA仲裁器优先级合理:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); // DCMI DMA优先级
HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0); // USB中断优先级更高
2. 优化时钟配置
- 问题分析:
USB需要精确的48MHz时钟,而DCMI的时钟(来自PLL3)可能导致PLL不稳定。
- 解决步骤:
- 独立配置USB时钟:
在SystemClock_Config()中确认USB时钟源为PLL1_Q或PLL3_Q,且分频后为48MHz:
RCC_PeriphCLKInitTypeDef periph_clk_init = {0};
periph_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USB;
periph_clk_init.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; // 使用PLL3专供USB
periph_clk_init.PLL3.PLL3M = 5; // VCO输入分频(根据HSE频率调整)
periph_clk_init.PLL3.PLL3N = 240; // VCO倍频
periph_clk_init.PLL3.PLL3Q = 10; // USB分频:240MHz/10=48MHz
HAL_RCCEx_PeriphCLKConfig(&periph_clk_init);
- 确保PLL带宽足够:
检查PLL配置是否支持DCMI像素时钟(参考摄像头规格)。
3. 总线拥塞处理
- 问题分析:
DCMI DMA传输占用大量AXI总线带宽(640×480×2≈600KB/frame),导致USB无法访问内存。
- 解决步骤:
- 使用DTCM内存存储USB数据:
将USB数据缓冲区定位在DTCM(0x20000000),独占式高速访问:
__attribute__((section(".dtcm"))) uint8_t usb_buffer[1024];
- 降低DCMI帧率或分辨率:
临时测试降低DCMI负载(如15fps),观察USB是否恢复:
// 调整摄像头配置(通过I2C或专用命令)
set_camera_framerate(15);
4. 验证PCB设计与供电
- 问题分析:
高速USB对信号质量敏感,DCMI的并行布线可能引入噪声。
- 解决步骤:
- 检查USB D+/D-差分线阻抗匹配(90Ω)。
- 确保USB3300的VBUS、3.3V供电无跌落(建议使用独立LDO)。
- 用示波器捕获DCMI的PIXCLK,确认无振铃或过冲。
5. 软件时序调整
- 问题分析:
USB枚举阶段对时序敏感,DCMI DMA启动可能干扰关键中断。
- 解决步骤:
- 延迟DCMI初始化:
在USB完全枚举成功后再启动DCMI:
HAL_PCD_Start(&hpcd); // 启动USB
while (usb_enumerated == false); // 等待USB枚举完成
MX_DCMI_Init(); // 初始化DCMI
- 启用缓存一致性操作(若使用Cache):
SCB_EnableDCache(); // 使能D-Cache
// DCMI DMA缓冲区配置为Write-Back
MPU_Config();
6. 检查STM32H750勘误手册
- 关键勘误项:
- ES0290:DCMI硬件同步模式下可能丢失数据(改用软件同步模式
DCMI_SYNCHRO_EMBEDDED)。
- ES0431:USB高速模式与DMA协同工作异常(更新固件库或调整DMA突发长度)。
总结排查流程
graph TD
A[USB中断停止] --> B{检查DMA冲突}
B --> |是| C[为USB分配BDMA]
B --> |否| D{检查时钟}
D --> |PLL不稳定| E[独立配置USB时钟]
D --> |正常| F{总线拥塞}
F --> |高带宽占用| G[使用DTCM内存+降帧率]
F --> |正常| H{硬件信号}
H --> |噪声干扰| I[优化电源/PCB]
H --> |正常| J[调整初始化时序]
按优先级执行以上步骤,90%以上的类似问题由DMA冲突或总线拥塞导致。建议从DMA配置切入,逐步验证其他环节。
针对STM32H750中同时使用USB HS Host(通过USB3300)和DCMI接口时USB中断停止工作的问题,以下是系统性解决方案:
1. 检查DMA冲突(最可能的原因)
- 问题分析:
DCMI默认使用DMA2,而USB可能隐式使用DMA(尤其是端点FIFO传输时)。DMA通道或流资源冲突会导致总线仲裁失败。
- 解决步骤:
- 为USB显式分配DMA通道:
在USB初始化代码中,确保为USB端点分配独立的DMA流(非DMA2),例如使用BDMA(专为低速外设设计):
// 在USB初始化前配置BDMA
HAL_RCC_BDMA_CLK_ENABLE();
hpcd.Init.dma_enable = 1;
hpcd.Init.phy_itface = USB_OTG_HS_ULPI_PHY;
hpcd.Init.Sof_enable = 1;
hpcd.Init.low_power_enable = 0;
hpcd.Init.dma_burst_length = USB_DMA_BURST_INCR4;
hpcd.hInstance = USB_OTG_HS;
hpcd.Instance = USB_OTG_HS;
HAL_PCD_Init(&hpcd);
- 检查DCMI的DMA流分配:
确保DCMI使用的DMA2流与USB或其他外设无重叠(参考STM32H750手册):
__HAL_RCC_DMA2_CLK_ENABLE();
hdma.Instance = DMA2_Stream1; // 避免使用Stream0(可能被DCMI默认占用)
HAL_DMA_Init(&hdma);
- 验证仲裁器配置:
在SystemClock_Config()中确保DMA仲裁器优先级合理:
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0); // DCMI DMA优先级
HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0); // USB中断优先级更高
2. 优化时钟配置
- 问题分析:
USB需要精确的48MHz时钟,而DCMI的时钟(来自PLL3)可能导致PLL不稳定。
- 解决步骤:
- 独立配置USB时钟:
在SystemClock_Config()中确认USB时钟源为PLL1_Q或PLL3_Q,且分频后为48MHz:
RCC_PeriphCLKInitTypeDef periph_clk_init = {0};
periph_clk_init.PeriphClockSelection = RCC_PERIPHCLK_USB;
periph_clk_init.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; // 使用PLL3专供USB
periph_clk_init.PLL3.PLL3M = 5; // VCO输入分频(根据HSE频率调整)
periph_clk_init.PLL3.PLL3N = 240; // VCO倍频
periph_clk_init.PLL3.PLL3Q = 10; // USB分频:240MHz/10=48MHz
HAL_RCCEx_PeriphCLKConfig(&periph_clk_init);
- 确保PLL带宽足够:
检查PLL配置是否支持DCMI像素时钟(参考摄像头规格)。
3. 总线拥塞处理
- 问题分析:
DCMI DMA传输占用大量AXI总线带宽(640×480×2≈600KB/frame),导致USB无法访问内存。
- 解决步骤:
- 使用DTCM内存存储USB数据:
将USB数据缓冲区定位在DTCM(0x20000000),独占式高速访问:
__attribute__((section(".dtcm"))) uint8_t usb_buffer[1024];
- 降低DCMI帧率或分辨率:
临时测试降低DCMI负载(如15fps),观察USB是否恢复:
// 调整摄像头配置(通过I2C或专用命令)
set_camera_framerate(15);
4. 验证PCB设计与供电
- 问题分析:
高速USB对信号质量敏感,DCMI的并行布线可能引入噪声。
- 解决步骤:
- 检查USB D+/D-差分线阻抗匹配(90Ω)。
- 确保USB3300的VBUS、3.3V供电无跌落(建议使用独立LDO)。
- 用示波器捕获DCMI的PIXCLK,确认无振铃或过冲。
5. 软件时序调整
- 问题分析:
USB枚举阶段对时序敏感,DCMI DMA启动可能干扰关键中断。
- 解决步骤:
- 延迟DCMI初始化:
在USB完全枚举成功后再启动DCMI:
HAL_PCD_Start(&hpcd); // 启动USB
while (usb_enumerated == false); // 等待USB枚举完成
MX_DCMI_Init(); // 初始化DCMI
- 启用缓存一致性操作(若使用Cache):
SCB_EnableDCache(); // 使能D-Cache
// DCMI DMA缓冲区配置为Write-Back
MPU_Config();
6. 检查STM32H750勘误手册
- 关键勘误项:
- ES0290:DCMI硬件同步模式下可能丢失数据(改用软件同步模式
DCMI_SYNCHRO_EMBEDDED)。
- ES0431:USB高速模式与DMA协同工作异常(更新固件库或调整DMA突发长度)。
总结排查流程
graph TD
A[USB中断停止] --> B{检查DMA冲突}
B --> |是| C[为USB分配BDMA]
B --> |否| D{检查时钟}
D --> |PLL不稳定| E[独立配置USB时钟]
D --> |正常| F{总线拥塞}
F --> |高带宽占用| G[使用DTCM内存+降帧率]
F --> |正常| H{硬件信号}
H --> |噪声干扰| I[优化电源/PCB]
H --> |正常| J[调整初始化时序]
按优先级执行以上步骤,90%以上的类似问题由DMA冲突或总线拥塞导致。建议从DMA配置切入,逐步验证其他环节。
举报