OpenEdv-开源电子网

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

摄像头驱动dma双缓冲传输完成中断只触发了一半

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
11
金钱
11
注册时间
2025-4-7
在线时间
2 小时
发表于 2025-8-4 18:26:17 | 显示全部楼层 |阅读模式
使用原子哥的摄像头实验例程,把DCMI->DR的数据先使用双缓冲模式存到AXI SRAM里面,例程里面是在内部ram里先保存一帧,但是我的图片1920*1200太大了,ram内存不够,所以我一行一行的搬运到sdram里。现在发现进入到DMA1_Stream1_IRQHandler里1200次,但是触发传输完成中断只有不到六百次,哪位大神有遇到过这个问题,卡了好几天了
int main(void)
{

  /* USER CODE BEGIN 1 */
        delay_init(400);                                               

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
        //SCB_DisableDCache();
        //SCB_DisableICache();
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DCMI_Init();
  MX_I2C1_Init();
  MX_FMC_Init();
  /* USER CODE BEGIN 2 */
       
        atksc233_init();
        Sdram_Init();
       
       
        //if (bsp_TestExtSDRAM() == 0)
        //{
    //printf("SDRAM Test success\r\n");
        //}
        //else
        //{
    //printf("SDRAM Test fail\r\n");
        //}
       
       
        SDRAM_Test();



        DCMI->IER=0x0;       
       
    __HAL_DCMI_ENABLE_IT(&hdcmi,DCMI_IT_FRAME);      //帧中断
    __HAL_DCMI_ENABLE(&hdcmi);                       //使能DCMI
                       
        dcmi_rx_callback=data_dcmi_rx_callback;
       
       
       
           __HAL_RCC_DMA1_CLK_ENABLE();                                    //ʹÄÜDMA1ʱÖÓ
    __HAL_LINKDMA(&hdcmi,DMA_Handle,hdma_dcmi);        //½«DMAÓëDCMIÁªÏµÆðÀ´
        __HAL_DMA_DISABLE_IT(&hdma_dcmi,DMA_IT_TC);                            //ÏȹرÕDMA´«ÊäÍê³ÉÖжÏ(·ñÔòÔÚʹÓÃMCUÆÁµÄʱºò»á³öÏÖ»¨ÆÁµÄÇé¿ö)
       
         __HAL_UNLOCK(&hdma_dcmi);
        // HAL_DMAEx_MultiBufferStart(&hdma_dcmi,(uint32_t)&DCMI->DR,(uint32_t)&dcmi_line_buf[0],(uint32_t)&dcmi_line_buf[1],1920/4);
         HAL_DMAEx_MultiBufferStart_IT(&hdma_dcmi,(uint32_t)&DCMI->DR,(uint32_t)&dcmi_line_buf[0],(uint32_t)&dcmi_line_buf[1],1920);
         DMA1_Stream1->CR &= ~DMA_IT_DME;
         DMA1_Stream1->CR &= ~DMA_IT_TE;
        DMA1_Stream1->CR |= DMA_IT_HT;
         
   __HAL_DMA_ENABLE_IT(&hdma_dcmi,DMA_IT_TC);   //开启传输完成中断

        //SCB_CleanInvalidateDCache();
        DCMI_Start();
       
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
        //HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, (uint32_t)jpeg_data_buf, 1920*1200/4);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
               
               
                HAL_GPIO_TogglePin(LED_RN_GPIO_Port, LED_RN_Pin);
                HAL_Delay(200);
               
               
          if (jpeg_data_ok == 1)
                {
                        // 数据已采集完成,确认是否完整写入 SDRAM
                        if (jpeg_frame_complete == 1)
                        {
                                // 数据完整,可以进行后续处理(如 JPEG 解码、传输等)
                                // 这里可以添加你的后续处理代码
                                // 标记数据已处理,准备下一帧采集
                                jpeg_data_ok = 2;
                                // 重置完整帧标记
                                jpeg_frame_complete = 0;
                        }
                        else
                        {
                                // 数据不完整,这里可以添加错误处理
                                // 例如:记录错误、重新启动采集等
                                // 简单处理:直接标记为已处理,开始新的采集
                                jpeg_data_ok = 2;
                        }
                }
                        // 可以在这里添加其他需要周期性执行的任务
               
                        //        DCMI_CheckStatus();
               
               
  }
  /* USER CODE END 3 */
}


DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma_dcmi;

/* DCMI init function */
void MX_DCMI_Init(void)
{

  /* USER CODE BEGIN DCMI_Init 0 */

       
  /* USER CODE END DCMI_Init 0 */

  /* USER CODE BEGIN DCMI_Init 1 */

  /* USER CODE END DCMI_Init 1 */
  hdcmi.Instance = DCMI;
  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;
  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_FALLING;
  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH;
  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_LOW;
  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();
  }
  /* USER CODE BEGIN DCMI_Init 2 */

       
       
  /* USER CODE END DCMI_Init 2 */

}

void HAL_DCMI_MspInit(DCMI_HandleTypeDef* dcmiHandle)
{

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

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

    __HAL_RCC_GPIOE_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    __HAL_RCC_GPIOG_CLK_ENABLE();
    /**DCMI GPIO Configuration
    PE5     ------> DCMI_D6
    PE6     ------> DCMI_D7
    PA4     ------> DCMI_HSYNC
    PA6     ------> DCMI_PIXCLK
    PC6     ------> DCMI_D0
    PC7     ------> DCMI_D1
    PC8     ------> DCMI_D2
    PC9     ------> DCMI_D3
    PC11     ------> DCMI_D4
    PD3     ------> DCMI_D5
    PG9     ------> DCMI_VSYNC
    */
    GPIO_InitStruct.Pin = DCMI_D6_GPIO_PIN_Pin|DCMI_D7_GPIO_PIN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = DCMI_HSYNC_GPIO_PIN_Pin|DCMI_PIXCLK_GPIO_PIN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = DCMI_D0_GPIO_PIN_Pin|DCMI_D1_GPIO_PIN_Pin|DCMI_D2_GPIO_PIN_Pin|DCMI_D3_GPIO_PIN_Pin
                          |DCMI_D4_GPIO_PIN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = DCMI_D5_GPIO_PIN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(DCMI_D5_GPIO_PIN_GPIO_Port, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = DCMI_VSYNC_GPIO_PIN_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
    HAL_GPIO_Init(DCMI_VSYNC_GPIO_PIN_GPIO_Port, &GPIO_InitStruct);

    /* DCMI DMA Init */
    /* DCMI Init */
    hdma_dcmi.Instance = DMA1_Stream1;
    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_WORD;
    hdma_dcmi.Init.Mode = DMA_CIRCULAR;
    hdma_dcmi.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_dcmi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
    hdma_dcmi.Init.MemBurst = DMA_MBURST_INC4;
    hdma_dcmi.Init.PeriphBurst = DMA_PBURST_SINGLE;
    if (HAL_DMA_Init(&hdma_dcmi) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(dcmiHandle,DMA_Handle,hdma_dcmi);

    /* DCMI interrupt Init */
    HAL_NVIC_SetPriority(DCMI_IRQn, 1, 2);
    HAL_NVIC_EnableIRQ(DCMI_IRQn);
  /* USER CODE BEGIN DCMI_MspInit 1 */
               
                HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 1); // 优先级可根据需求调整(建议高于DCMI)
        HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
                //HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)dcmi_line_buf[0], jpeg_line_size);
               
  }
}


volatile uint32_t j = 0;
volatile uint32_t k = 0;
void DMA1_Stream1_IRQHandler(void)
{
        j++;
  /* USER CODE BEGIN DMA1_Stream1_IRQn 0 */
        if((DMA1->LISR & DMA_LISR_TCIF1) != 0)
        {
                        //清除传输完成中断标志
                        DMA1->LIFCR = DMA_LIFCR_CTCIF1;
                        k++;
                        //执行用户回调函数
                        dcmi_rx_callback();
        }
       
  /* USER CODE END DMA1_Stream1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_dcmi);
  /* USER CODE BEGIN DMA1_Stream1_IRQn 1 */

       

        //HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_SNAPSHOT, 0xC0000000, 1920*1200/4);
       
  /* USER CODE END DMA1_Stream1_IRQn 1 */
}

/**
  * @brief This function handles DCMI global interrupt.
  */
void DCMI_IRQHandler(void)
{
  /* USER CODE BEGIN DCMI_IRQn 0 */

  /* USER CODE END DCMI_IRQn 0 */
  HAL_DCMI_IRQHandler(&hdcmi);
  /* USER CODE BEGIN DCMI_IRQn 1 */

  /* USER CODE END DCMI_IRQn 1 */
}

/* USER CODE BEGIN 1 */
volatile uint32_t csfinishj = 0;
volatile uint32_t csfinishk = 0;
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi) //帧中断
{
        csfinishj = j;
        csfinishk = k;
        j = 0;
        k = 0;
        jpeg_data_process();
   __HAL_DCMI_ENABLE_IT(hdcmi,DCMI_IT_FRAME);
       
}

void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-8-17 17:51

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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