打印

STM32H7的摄像头接口DCMI配套的函数HAL_DCMI_Start_DMA非常不错,支持大分辨率直接传输

[复制链接]
583|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
社畜一枚|  楼主 | 2018-8-9 21:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
函数HAL_DCMI_Start_DMA封装的通用定时器DMA1,DMA2。使用这个定时器的特点是限制单轮最大65535次传输,这样使用大分辨率摄像头非常不方便。

使用这个函数的话,解决了这个问题,程序里面做了一个处理,对于需要大于65536次传输的情况,使用了双缓冲,不断动态调整地址,直到一帧传输完毕后会使能DCMI的帧中断



/**
  * @brief  Enables DCMI DMA request and enables DCMI capture  
  * @param  hdcmi:     pointer to a DCMI_HandleTypeDef structure that contains
  *                    the configuration information for DCMI.
  * @param  DCMI_Mode: DCMI capture mode snapshot or continuous grab.
  * @param  pData:     The destination memory Buffer address (LCD Frame buffer).
  * @param  Length:    The length of capture to be transferred.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)
{  
  /* Initialize the second memory address */
  uint32_t SecondMemAddress = 0;

  /* Check function parameters */
  assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode));

  /* Process Locked */
  __HAL_LOCK(hdcmi);
  
  /* Lock the DCMI peripheral state */
  hdcmi->State = HAL_DCMI_STATE_BUSY;

  /* Enable DCMI by setting DCMIEN bit */
  __HAL_DCMI_ENABLE(hdcmi);
  
  /* Configure the DCMI Mode */
  hdcmi->Instance->CR &= ~(DCMI_CR_CM);
  hdcmi->Instance->CR |=  (uint32_t)(DCMI_Mode);

  /* Set the DMA memory0 conversion complete callback */
  hdcmi->DMA_Handle->XferCpltCallback = DCMI_DMAXferCplt;

  /* Set the DMA error callback */
  hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;

  /* Set the dma abort callback */
  hdcmi->DMA_Handle->XferAbortCallback = NULL;

  /* Reset transfer counters value */
  hdcmi->XferCount = 0;
  hdcmi->XferTransferNumber = 0;
  
  if(Length <= 0xFFFF)
  {
    /* Enable the DMA Stream */
    HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length);
  }
  else /* DCMI_DOUBLE_BUFFER Mode */
  {
    /* Set the DMA memory1 conversion complete callback */
    hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAXferCplt;

    /* Initialize transfer parameters */
    hdcmi->XferCount = 1;
    hdcmi->XferSize = Length;
    hdcmi->pBuffPtr = pData;
      
    /* Get the number of buffer */
    while(hdcmi->XferSize > 0xFFFF)
    {
      hdcmi->XferSize = (hdcmi->XferSize/2);
      hdcmi->XferCount = hdcmi->XferCount*2;
    }

    /* Update DCMI counter  and transfer number*/
    hdcmi->XferCount = (hdcmi->XferCount - 2);
    hdcmi->XferTransferNumber = hdcmi->XferCount;

    /* Update second memory address */
    SecondMemAddress = (uint32_t)(pData + (4*hdcmi->XferSize));

    /* Start DMA multi buffer transfer */
    HAL_DMAEx_MultiBufferStart_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, SecondMemAddress, hdcmi->XferSize);
  }
  
  /* Enable Capture */
  hdcmi->Instance->CR |= DCMI_CR_CAPTURE;

  /* Release Lock */
  __HAL_UNLOCK(hdcmi);

  /* Return function status */
  return HAL_OK;
}

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

397

主题

401

帖子

0

粉丝