本帖最后由 mrhw 于 2014-6-29 10:58 编辑  
 
项目所用MCU型号是STM32F207VCT6, 使用TVP5150视频模数转换芯片,将模拟视频信号转换为带外同步数字信号通过DCMI接收,接收的数据大小是4行,为调试方便,暂且接收一个字节。 
 
在调用以下程序之前已经对TVP5150进行了初始化,TVP5150已经可以输出50HZ的 Vsync 垂直同步信号,16.625K的Hsync水平同步信号,同步信号全部是上升沿触发,TVP5150同时输出PIXCK(像素时钟)27M,也是上升沿数据有效。 
 
程序通过以下几个步骤进行初始化:关键1间接调用关键2,关键2间接调用关键3, 最终完成了初始化 
 
关键4 启动DCMI-DMA接收的, 
 
现在的问题是:一旦调用关键4,DCMI_DMAError 会被立即触发,DMA失败。 
 
关键1. 
void MX_DCMI_Init(void) 
{ 
 
  hdcmi.Instance = DCMI; 
  hdcmi.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; 
  hdcmi.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING; //1 
  hdcmi.Init.VSPolarity = DCMI_VSPOLARITY_HIGH; //2 
  hdcmi.Init.HSPolarity = DCMI_HSPOLARITY_HIGH;//3  通过对123 取不同值也不行 
  hdcmi.Init.CaptureRate = DCMI_CR_ALL_FRAME; 
  hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; 
  hdcmi.Init.JPEGMode = DCMI_JPEG_DISABLE; 
  HAL_DCMI_Init(&hdcmi); //关键2 
 
} 
 
关键2. 
HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi) 
{      
  /* Check the DCMI peripheral state */ 
  if(hdcmi == NULL) 
  { 
     return HAL_ERROR; 
  } 
   
  /* Check function parameters */ 
  assert_param(IS_DCMI_ALL_INSTANCE(hdcmi->Instance)); 
  assert_param(IS_DCMI_PCKPOLARITY(hdcmi->Init.PCKPolarity)); 
  assert_param(IS_DCMI_VSPOLARITY(hdcmi->Init.VSPolarity)); 
  assert_param(IS_DCMI_HSPOLARITY(hdcmi->Init.HSPolarity)); 
  assert_param(IS_DCMI_SYNCHRO(hdcmi->Init.SynchroMode)); 
  assert_param(IS_DCMI_CAPTURE_RATE(hdcmi->Init.CaptureRate)); 
  assert_param(IS_DCMI_EXTENDED_DATA(hdcmi->Init.ExtendedDataMode)); 
  assert_param(IS_DCMI_MODE_JPEG(hdcmi->Init.JPEGMode)); 
 
  if(hdcmi->State == HAL_DCMI_STATE_RESET) 
  { 
    /* Init the low level hardware */ 
    HAL_DCMI_MspInit(hdcmi); //关键3 
  }  
   
  /* Change the DCMI state */ 
  hdcmi->State = HAL_DCMI_STATE_BUSY;  
 
  /* Configures the HS, VS, DE and PC polarity */ 
  hdcmi->Instance->CR &= ~(DCMI_CR_PCKPOL | DCMI_CR_HSPOL  | DCMI_CR_VSPOL  | DCMI_CR_EDM_0 | 
                           DCMI_CR_EDM_1  | DCMI_CR_FCRC_0 | DCMI_CR_FCRC_1 | DCMI_CR_JPEG  | 
                           DCMI_CR_ESS); 
  hdcmi->Instance->CR |=  (uint32_t)(hdcmi->Init.SynchroMode | hdcmi->Init.CaptureRate | \ 
                                     hdcmi->Init.VSPolarity  | hdcmi->Init.HSPolarity  | \ 
                                     hdcmi->Init.PCKPolarity | hdcmi->Init.ExtendedDataMode | \ 
                                     hdcmi->Init.JPEGMode); 
 
  if(hdcmi->Init.SynchroMode == DCMI_SYNCHRO_EMBEDDED) 
  { 
    DCMI->ESCR = (((uint32_t)hdcmi->Init.SyncroCode.FrameStartCode)    | 
                  ((uint32_t)hdcmi->Init.SyncroCode.LineStartCode << 8)| 
                  ((uint32_t)hdcmi->Init.SyncroCode.LineEndCode << 16) | 
                  ((uint32_t)hdcmi->Init.SyncroCode.FrameEndCode << 24)); 
  } 
 
  /* Enable the Line interrupt */ 
  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_LINE); 
 
  /* Enable the VSYNC interrupt */ 
  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_VSYNC); 
 
  /* Enable the Frame capture complete interrupt */ 
  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_FRAME); 
 
  /* Enable the Synchronization error interrupt */ 
  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_ERR); 
 
  /* Enable the Overflow interrupt */ 
  __HAL_DCMI_ENABLE_IT(hdcmi, DCMI_IT_OVF); 
 
  /* Enable DCMI by setting DCMIEN bit */ 
  __HAL_DCMI_ENABLE(hdcmi);   //DCMI已经使能了 
 
  /* Update error code */ 
  hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE; 
   
  /* Initialize the DCMI state*/ 
  hdcmi->State  = HAL_DCMI_STATE_READY; 
 
  return HAL_OK; 
} 
 
关键3. 
 
void HAL_DCMI_MspInit(DCMI_HandleTypeDef* hdcmi) 
{ 
 
  GPIO_InitTypeDef GPIO_InitStruct; 
  if(hdcmi->Instance==DCMI) 
  { 
    /* Peripheral clock enable */ 
    __DCMI_CLK_ENABLE(); 
   
    /**DCMI GPIO Configuration     
    PE4     ------> DCMI_D4 
    PE5     ------> DCMI_D6 
    PE6     ------> DCMI_D7 
    PA4     ------> DCMI_HSYNC 
    PA6     ------> DCMI_PIXCK 
    PC6     ------> DCMI_D0 
    PC7     ------> DCMI_D1 
    PC8     ------> DCMI_D2 
    PC9     ------> DCMI_D3 
    PB6     ------> DCMI_D5 
    PB7     ------> DCMI_VSYNC  
    */ 
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Pull = GPIO_NOPULL; 
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; 
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); 
 
    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_6; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Pull = GPIO_NOPULL; 
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; 
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
 
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Pull = GPIO_NOPULL; 
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; 
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 
 
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; 
    GPIO_InitStruct.Pull = GPIO_NOPULL; 
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; 
    GPIO_InitStruct.Alternate = GPIO_AF13_DCMI; 
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); 
 
    /* Peripheral DMA init*/ 
   
    hdma_dcmi.Instance = DMA2_Stream1; 
    hdma_dcmi.Init.Channel = DMA_CHANNEL_1; 
    hdma_dcmi.Init.Direction = DMA_PERIPH_TO_MEMORY; 
    hdma_dcmi.Init.PeriphInc = DMA_PINC_DISABLE; 
    hdma_dcmi.Init.MemInc = DMA_MINC_DISABLE; 
    hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; 
    hdma_dcmi.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; 
    hdma_dcmi.Init.Mode = DMA_NORMAL; // 这里改为循环模式也不行 
    hdma_dcmi.Init.Priority = DMA_PRIORITY_VERY_HIGH; 
    hdma_dcmi.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 
    HAL_DMA_Init(&hdma_dcmi);  //dma已经初始化好了,没有使能 
 
    __HAL_LINKDMA(hdcmi,DMA_Handle,hdma_dcmi); 
 
    /* Peripheral interrupt init*/ 
    /* Sets the priority grouping field */ 
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); 
    HAL_NVIC_SetPriority(DCMI_IRQn, 2, 0); 
    HAL_NVIC_EnableIRQ(DCMI_IRQn); 
  } 
 
} 
 
关键 4  调用 HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, (uint32_t)&data1, 1); //会立即触发DMA错误,&data1数据没有改变 
 
HAL_StatusTypeDef HAL_DCMI_Start_DMA(DCMI_HandleTypeDef* hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length) 
{   
  /* Initialise 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; 
 
  /* Check the parameters */ 
  assert_param(IS_DCMI_CAPTURE_MODE(DCMI_Mode)); 
 
  /* 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_DMAConvCplt; 
 
  /* Set the DMA error callback */ 
  hdcmi->DMA_Handle->XferErrorCallback = DCMI_DMAError;  //这个 DCMI_DMAError 会被立即触发 
 
  if(Length <= 0xFFFF) 
  { 
    /* Enable the DMA Stream */    //步骤5 
    HAL_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)&hdcmi->Instance->DR, (uint32_t)pData, Length);//这里面使能了DMA 
  } 
  else /* DCMI_DOUBLE_BUFFER Mode */ 
  { 
    /* Set the DMA memory1 conversion complete callback */ 
    hdcmi->DMA_Handle->XferM1CpltCallback = DCMI_DMAConvCplt;  
 
    /* Initialise 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 */ 
  DCMI->CR |= DCMI_CR_CAPTURE; //启动捕获图像 
 
  /* Return function status */ 
  return HAL_OK; 
} 
 
 
 
 
 
 |   
     
  
 |