H7 DCMI 进DCMI中断后,总是进Overflow interrupt management部分,且DMA中断错误

2019-07-20 01:10发布

我用自己的STM32H750的板子,用MX生成了代码,调DCMI接口,接收前端FPGA过来的YUV422的数据,debug发现在进HAL_DCMI_IRQHandler()的时候总是进入了Overflow interrupt management,且接收不到数据,而且DMA中断HAL_DMA_IRQHandler()总是进传输错误部分,这个是哪里出了问题不太清楚啊。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
Levi123456
1楼-- · 2019-07-20 02:17
该问题已经解决了,解决的办法是将keil中的IRAM2勾选上,但是具体的原因和原理还不是很清楚,内存不够了?还有H7的IRAM1和IRAM2分别代表片内SRAM的什么不太清楚,为什么要分为IRAM1和IRAM2不是太清楚,求大神指点
Levi123456
2楼-- · 2019-07-20 02:32
uint8_t yuvbuf[640*2];//
int main(void)
{
  SCB_EnableICache();

  SCB_EnableDCache();

  HAL_Init()

  SystemClock_Config();


MX_DCMI_Init();
HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)yuvbuf, 640);

while(1)
{
                        delay_cnt(1000);
}

}


/**************************************************/
static void MX_DCMI_Init(void)
{
  hdcmi.Instance = DCMI;
  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;
  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_HIGH;
  hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME;
  hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;
//  hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE;
//  hdcmi.Init.ByteSelectMode = DCMI_BSM_ALL;
//  hdcmi.Init.ByteSelectStart = DCMI_OEBS_ODD;
//  hdcmi.Init.LineSelectMode = DCMI_LSM_ALL;
//  hdcmi.Init.LineSelectStart = DCMI_OELS_ODD;
  if (HAL_DCMI_Init(&hdcmi) != HAL_OK)
  {
    Error_Handler();
  }

}


/*********************************************/
void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hdcmi->Instance==DCMI)
  {
  /* USER CODE BEGIN DCMI_MspInit 0 */

  /* USER CODE END DCMI_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_DCMI_CLK_ENABLE();

    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOI_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOH_CLK_ENABLE();
    /**DCMI GPIO Configuration   
    PE1     ------> DCMI_D3
    PE0     ------> DCMI_D2
    PE4     ------> DCMI_D4
    PI7     ------> DCMI_D7
    PI6     ------> DCMI_D6
    PI5     ------> DCMI_VSYNC
    PI4     ------> DCMI_D5
    PA9     ------> DCMI_D0
    PC7     ------> DCMI_D1
    PH8     ------> DCMI_HSYNC
    PA6     ------> DCMI_PIXCLK
    */
    GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_0|GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);

    /* DCMI DMA Init */
                __HAL_RCC_DMA1_CLK_ENABLE();
    /* DCMI Init */
    hdma_dcmi.Instance = DMA1_Stream0;
    hdma_dcmi.Init.Request = DMA_REQUEST_DCMI;
    hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_dcmi.Init.MemInc = DMA_MINC_ENABLE;
    hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_dcmi.Init.Mode = DMA_CIRCULAR;//--DMA_NORMAL;
    hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;//--DMA_PRIORITY_LOW;
                hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;//--DMA_FIFOMODE_ENABLE;
    hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;//DMA_FIFO_THRESHOLD_FULL;
    hdma_dcmi.Init.MemBurst = DMA_MBURST_SINGLE;
    hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;

    __HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi);

    /* DCMI interrupt Init */
    HAL_NVIC_SetPriority(DCMI_IRQn, 0x0F, 0);
    HAL_NVIC_EnableIRQ(DCMI_IRQn);
  /* USER CODE BEGIN DCMI_MspInit 1 */

                  /* DMA interrupt init */
                /* DMA1_Stream0_IRQn interrupt configuration */
                HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0x0F, 0);
                HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);

     if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK)//++
    {
      Error_Handler();
    }
  /* USER CODE END DCMI_MspInit 1 */
  }

}


结果DCMI中断总是进 Overflow interrupt management
/******************************************************/
void HAL_DCMI_IRQHandler(DCMI_HandleTypeDef *hdcmi)
{
  uint32_t isr_value = READ_REG(hdcmi->Instance->MISR);

  /* Synchronization error interrupt management *******************************/
  if((isr_value & DCMI_FLAG_ERRRI) == DCMI_FLAG_ERRRI)
  {
    /* Clear the Synchronization error flag */
    __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_ERRRI);

    /* Update error code */
    hdcmi->ErrorCode |= HAL_DCMI_ERROR_SYNC;

    /* Change DCMI state */
    hdcmi->State = HAL_DCMI_STATE_ERROR;

    /* Set the synchronization error callback */
    hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;

    /* Abort the DMA Transfer */
    (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
  }
  /* Overflow interrupt management ********************************************/
  if((isr_value & DCMI_FLAG_OVRRI) == DCMI_FLAG_OVRRI)
  {
    /* Clear the Overflow flag */
    __HAL_DCMI_CLEAR_FLAG(hdcmi, DCMI_FLAG_OVRRI);

    /* Update error code */
    hdcmi->ErrorCode |= HAL_DCMI_ERROR_OVR;

    /* Change DCMI state */
    hdcmi->State = HAL_DCMI_STATE_ERROR;

    /* Set the overflow callback */
    hdcmi->DMA_Handle->XferAbortCallback = DCMI_DMAError;

    /* Abort the DMA Transfer */
    (void)HAL_DMA_Abort_IT(hdcmi->DMA_Handle);
  }

......
}

而DCMI的DMA中断总是进Transfer Error Interrupt management
/********************************************************/
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
  uint32_t tmpisr_dma, tmpisr_bdma;
  uint32_t ccr_reg;
  __IO uint32_t count = 0U;
  uint32_t timeout = SystemCoreClock / 9600U;

  /* calculate DMA base and stream number */
  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;

  tmpisr_dma  = regs_dma->ISR;
  tmpisr_bdma = regs_bdma->ISR;

  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
  {
    /* Transfer Error Interrupt management ***************************************/
    if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
    {
      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
      {
        /* Disable the transfer error interrupt */
        ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TE);

        /* Clear the transfer error flag */
        regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);

        /* Update error code */
        hdma->ErrorCode |= HAL_DMA_ERROR_TE;
      }
    }


....
}

不知道是哪里出了问题
正点原子
3楼-- · 2019-07-20 08:02
 精彩回答 2  元偷偷看……
Levi123456
4楼-- · 2019-07-20 09:21
 精彩回答 2  元偷偷看……
正点原子
5楼-- · 2019-07-20 12:42
Levi123456 发表于 2019-6-18 09:11
还有一个附带的问题,就是每次编译的时候的.sct文件是自动重新生成的吗?要是我想修改.sct文件,修改了后重 ...

不是,.sct是你自己编写的。不会每次都改,得你自己改。
Levi123456
6楼-- · 2019-07-20 13:30
 精彩回答 2  元偷偷看……

一周热门 更多>