函数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;
} |