OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3541|回复: 8

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

[复制链接]

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
发表于 2019-6-17 13:29:23 | 显示全部楼层 |阅读模式
1金钱
我用自己的STM32H750的板子,用MX生成了代码,调DCMI接口,接收前端FPGA过来的YUV422的数据,debug发现在进HAL_DCMI_IRQHandler()的时候总是进入了Overflow interrupt management,且接收不到数据,而且DMA中断HAL_DMA_IRQHandler()总是进传输错误部分,这个是哪里出了问题不太清楚啊。

最佳答案

查看完整内容[请看2#楼]

该问题已经解决了,解决的办法是将keil中的IRAM2勾选上,但是具体的原因和原理还不是很清楚,内存不够了?还有H7的IRAM1和IRAM2分别代表片内SRAM的什么不太清楚,为什么要分为IRAM1和IRAM2不是太清楚,求大神指点
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-17 13:29:24 | 显示全部楼层
该问题已经解决了,解决的办法是将keil中的IRAM2勾选上,但是具体的原因和原理还不是很清楚,内存不够了?还有H7的IRAM1和IRAM2分别代表片内SRAM的什么不太清楚,为什么要分为IRAM1和IRAM2不是太清楚,求大神指点
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-17 13:38:49 | 显示全部楼层
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;
      }
    }


....
}

不知道是哪里出了问题
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-6-18 02:21:42 | 显示全部楼层
帮顶
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-18 09:11:53 | 显示全部楼层
还有一个附带的问题,就是每次编译的时候的.sct文件是自动重新生成的吗?要是我想修改.sct文件,修改了后重新keil编译代码,会不会覆盖掉我原来的.sct文件呢
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2019-6-19 01:10:52 | 显示全部楼层
Levi123456 发表于 2019-6-18 09:11
还有一个附带的问题,就是每次编译的时候的.sct文件是自动重新生成的吗?要是我想修改.sct文件,修改了后重 ...

不是,.sct是你自己编写的。不会每次都改,得你自己改。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-19 09:10:13 | 显示全部楼层
正点原子 发表于 2019-6-19 01:10
不是,.sct是你自己编写的。不会每次都改,得你自己改。

好的,谢谢大佬,不过现在还没用到修改.sct的地方。
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-19 09:12:40 | 显示全部楼层
关于IRAM1 IRAM2以及Code RO RW ZI的一些相关资料我网上查了一些资料,感觉有一些写得比较好:
https://www.cnblogs.com/yangguang-it/p/7697967.html
回复

使用道具 举报

8

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
50
金钱
50
注册时间
2019-6-14
在线时间
13 小时
 楼主| 发表于 2019-6-20 10:40:29 | 显示全部楼层
正点原子 发表于 2019-6-19 01:10
不是,.sct是你自己编写的。不会每次都改,得你自己改。

网上查了一下资料,关于选择 sct 文件的产生方式:
首先需要选择 sct 文件产生的方式,选择使用 MDK 生成还是使用用户自定义的 sct 文件。在 MDK 的“Options for Target->Linker->Use Memory Layout from Target Dialog”选项即可配置该选择。该选项的译文为“是否使用 Target 对话框中的存储器分布配置”,勾选后,它会根据“Options for Target”对话框中的选项生成 sct 文件,这种情况下,即使我们手动打开它生成的 sct 文件编辑也是无效的,因为每次构建工程的时候, MDK 都会生成新的 sct 文件覆盖旧文件。该选项在 MDK 中是默认勾选的,若希望 MDK 使用我们手动编辑的 sct 文件构建工程,需要取消勾选,并通过 Scatter File 框中指定 sct 文件的路径。

使用MDK生成sct文件

使用MDK生成sct文件

使用指定的sct文件构建工程

使用指定的sct文件构建工程
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-16 17:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表