STM32
直播中

陈静

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

STM32H750 USB HS HOST 加 DCMI 接口不能正常工作怎么解决?

我目前使用STM32H750加USB3300用做USB高速host,然后通过通过DCMI接口读取摄像头数据,摄像头的分辨率是640480(640480*2bytes)。
单独打开USB时,usb是工作正常的。
单独打开DCMI时,也是可以正常工作的。
如果打开USB后,再打开DCMI后,启动dma传输,usb就工作了,没有usb中断发生。
DCMI初始化代码
HAL_RCC_DMA2_CLK_DISABLE();HAL_RCC_DCMI_CLK_DISABLE();HAL_RCC_DMA2_CLK_ENABLE();HAL_RCC_DCMI_CLK_ENABLE();
DCMI_InitStructure.Instance = DCMI;DCMI_InitStructure.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;   // 硬件同步DCMI_InitStructure.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING; // 像素时钟上升沿采样DCMI_InitStructure.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;     // VSYNC高有效DCMI_InitStructure.Init.HSPolarity = DCMI_HSPOLARITY_LOW;     // HSYNC高有效DCMI_InitStructure.Init.CaptureRate = DCMI_CR_ALL_FRAME;       // 捕获全帧DCMI_InitStructure.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // 数据宽度(根据摄像头配置)HAL_DCMI_Init(&DCMI_InitStructure);
HAL_NVIC_SetPriority(DCMI_IRQn, 5, 0);HAL_NVIC_EnableIRQ(DCMI_IRQn);
// 2. 配置DMA句柄(DMA2 Stream1用于DCMI)DMA_InitStructure.Instance                  = DMA2_Stream1;DMA_InitStructure.Init.Request              = DMA_REQUEST_DCMI;             // DMA请求源为DCMIDMA_InitStructure.Init.Direction            = DMA_PERIPH_TO_MEMORY;         // 传输方向:外设到内存DMA_InitStructure.Init.PeriphInc            = DMA_PINC_DISABLE;             // 外设地址不递增DMA_InitStructure.Init.MemInc               = DMA_MINC_ENABLE;              // 内存地址递增DMA_InitStructure.Init.PeriphDataAlignment  = DMA_PDATAALIGN_WORD;          // 外设数据对齐32位DMA_InitStructure.Init.MemDataAlignment     = DMA_MDATAALIGN_WORD;          // 内存数据对齐32位DMA_InitStructure.Init.Mode                 = DMA_CIRCULAR;                 // 循环模式(自动切换缓冲)DMA_InitStructure.Init.Priority             = DMA_PRIORITY_LOW;             // 高优先级DMA_InitStructure.Init.FIFOMode             = DMA_FIFOMODE_ENABLE;          // 启用FIFODMA_InitStructure.Init.FIFOThreshold        = DMA_FIFO_THRESHOLD_FULL;      // FIFO阈值HAL_DMA_Init(&DMA_InitStructure);
// 3. 绑定DMA到DCMI__HAL_LINKDMA(&DCMI_InitStructure, DMA_Handle, DMA_InitStructure);
// 外部SDRAM
camera_buff = mymalloc(SRAMEX, 2CAMERA_WIDTHCAMERA_HIGH*2);
HAL_DCMI_Start_DMA(&DCMI_InitStructure,DCMI_MODE_CONTINUOUS, (uint32_t)camera_buff, CAMERA_WIDTHCAMERA_HIGH2/4);
USB初始化代码
HAL_PWREx_EnableUSBVoltageDetector();
USBH_Init(&hUSBHost, USBH_UserProcess, 0);
USBH_RegisterClass(&hUSBHost, USBH_VIDEO_CLASS);
USBH_Start(&hUSBHost);

回帖(1)

h1654155598.0450

2025-7-30 18:01:39

针对STM32H750中同时使用USB HS Host(通过USB3300)和DCMI接口时USB中断停止工作的问题,以下是系统性解决方案:




1. 检查DMA冲突(最可能的原因)



  • 问题分析

    DCMI默认使用DMA2,而USB可能隐式使用DMA(尤其是端点FIFO传输时)。DMA通道或流资源冲突会导致总线仲裁失败。

  • 解决步骤

    1. 为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);

    2. 检查DCMI的DMA流分配

      确保DCMI使用的DMA2流与USB或其他外设无重叠(参考STM32H750手册):
      __HAL_RCC_DMA2_CLK_ENABLE();
      hdma.Instance = DMA2_Stream1; // 避免使用Stream0(可能被DCMI默认占用)
      HAL_DMA_Init(&hdma);

    3. 验证仲裁器配置

      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不稳定。

  • 解决步骤

    1. 独立配置USB时钟

      SystemClock_Config()中确认USB时钟源为PLL1_QPLL3_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);

    2. 确保PLL带宽足够

      检查PLL配置是否支持DCMI像素时钟(参考摄像头规格)。





3. 总线拥塞处理



  • 问题分析

    DCMI DMA传输占用大量AXI总线带宽(640×480×2≈600KB/frame),导致USB无法访问内存。

  • 解决步骤

    1. 使用DTCM内存存储USB数据

      将USB数据缓冲区定位在DTCM(0x20000000),独占式高速访问:
      __attribute__((section(".dtcm"))) uint8_t usb_buffer[1024];

    2. 降低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启动可能干扰关键中断。

  • 解决步骤

    1. 延迟DCMI初始化

      在USB完全枚举成功后再启动DCMI:
       HAL_PCD_Start(&hpcd); // 启动USB
      while (usb_enumerated == false); // 等待USB枚举完成
      MX_DCMI_Init();       // 初始化DCMI

    2. 启用缓存一致性操作(若使用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配置切入,逐步验证其他环节。

举报

更多回帖

×
20
完善资料,
赚取积分