其他分享
首页 > 其他分享> > STM32H743中的DCMI无法进入行中断和场中断问题

STM32H743中的DCMI无法进入行中断和场中断问题

作者:互联网

今天在玩MT9V034摄像头时,用到了DCMI接口处理摄像头的数据,出现了一个BUG,怎么都进入不了行中断或者场中断。究其原因,原来是忘记设置其中断优先级了。


void Msp_DCMI_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	__HAL_RCC_DCMI_CLK_ENABLE();
	__HAL_RCC_GPIOH_CLK_ENABLE();
	__HAL_RCC_GPIOI_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 工作模式,推挽复用
  GPIO_InitStruct.Pull = GPIO_PULLUP;         // 不使用上拉输出
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;// I/O操作速度 非常高	
	GPIO_InitStruct.Alternate = GPIO_AF13_DCMI;
			
  GPIO_InitStruct.Pin = DCMI_D0;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D1;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D2;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D3;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D4;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D5;HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D6;HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D7;HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D8;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_D9;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_HSYNC_PIN;HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_VSYNC_PIN;HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
  GPIO_InitStruct.Pin = DCMI_PXCLK_PIN;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
	
}

// DCMI configuration
uint8_t DCMI_Init(void)
{ 
	 // DCMI configuration
    DCMIHandle.Instance         = DCMI;
    // VSYNC clock polarity
    DCMIHandle.Init.VSPolarity  = DCMI_VSPOLARITY_LOW;             
    // HSYNC clock polarity
    DCMIHandle.Init.HSPolarity  = DCMI_HSPOLARITY_LOW;
    // PXCLK clock polarity
    DCMIHandle.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;

    DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE;    // Enable Hardware synchronization
    DCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME;        // Capture rate all frames
    DCMIHandle.Init.ExtendedDataMode = DCMI_EXTEND_DATA_10B; // Capture 8 bits on every pixel clock
    //DCMIHandle.Init.JPEGMode = DCMI_JPEG_ENABLE;                   // Set JPEG Mode
	  
    #if defined(STM32F765xx)||defined(STM32F769xx)||defined(STM32H743xx)
    DCMIHandle.Init.ByteSelectMode  = DCMI_BSM_ALL;         // Capture all received bytes
    DCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD;        // Ignored
    DCMIHandle.Init.LineSelectMode  = DCMI_LSM_ALL;         // Capture all received lines
    DCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD;        // Ignored
    #endif

    // Associate the DMA handle to the DCMI handle
		DCMI->IER=0x0;
		
		__HAL_DCMI_ENABLE_IT(&DCMIHandle,DCMI_IT_FRAME);      //使能帧中断
		HAL_NVIC_SetPriority(DCMI_IRQn, 1, 2);
    HAL_NVIC_EnableIRQ(DCMI_IRQn);
		
    __HAL_DCMI_ENABLE(&DCMIHandle);                       //使能DCMI
		
    

   // Initialize the DCMI
    HAL_DCMI_DeInit(&DCMIHandle);
		
    if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {
        // Initialization Error
        return -1;
    }
    return 0;
	
}


// DMA Stream configuration
//mem0addr:存储器地址0  将要存储摄像头数据的内存地址(也可以是外设地址)
//mem1addr:存储器地址1  当只使用mem0addr的时候,该值必须为0
//memblen:存储器位宽,可以为:DMA_MDATAALIGN_BYTE/DMA_MDATAALIGN_HALFWORD/DMA_MDATAALIGN_WORD
//meminc:存储器增长方式,可以为:DMA_MINC_ENABLE/DMA_MINC_DISABLE
uint8_t DMA1_DCMI_Init(uint32_t mem0addr,uint32_t mem1addr,uint16_t memsize,uint32_t memblen,uint32_t meminc)
{
	
	  __HAL_RCC_DMA1_CLK_ENABLE();
	  
	  __HAL_LINKDMA(&DCMIHandle, DMA_Handle, DMA1_DMCIHandle);
	  __HAL_DMA_DISABLE_IT(&DMA1_DMCIHandle,DMA_IT_TC);   //关闭DMA传输完成中断
	
	
    DMA1_DMCIHandle.Instance              = DMA1_Stream1;             /* Select the DMA instance          */
    DMA1_DMCIHandle.Init.Request          = DMA_REQUEST_DCMI;            /* DMA Channel                   */
    DMA1_DMCIHandle.Init.Direction        = DMA_PERIPH_TO_MEMORY;     /* Peripheral to memory transfer    */
    DMA1_DMCIHandle.Init.MemInc           = meminc;                   /* Memory increment mode Enable     */
    DMA1_DMCIHandle.Init.PeriphInc        = DMA_PINC_DISABLE;         /* Peripheral increment mode Enable */
    DMA1_DMCIHandle.Init.PeriphDataAlignment  = DMA_PDATAALIGN_WORD;  /* Peripheral data alignment : Word */
    DMA1_DMCIHandle.Init.MemDataAlignment = memblen;                  /* Memory data alignment : Word     */
    DMA1_DMCIHandle.Init.Mode             = DMA_NORMAL;               /* Normal DMA mode                  */
    DMA1_DMCIHandle.Init.Priority         = DMA_PRIORITY_HIGH;        /* Priority level : high            */
    DMA1_DMCIHandle.Init.FIFOMode         = DMA_FIFOMODE_ENABLE;      /* FIFO mode enabled                */
    DMA1_DMCIHandle.Init.FIFOThreshold    = DMA_FIFO_THRESHOLD_HALFFULL;  /* FIFO threshold full          */
    DMA1_DMCIHandle.Init.MemBurst         = DMA_MBURST_SINGLE;          /* Memory burst                   */
    DMA1_DMCIHandle.Init.PeriphBurst      = DMA_PBURST_SINGLE;        /* Peripheral burst                 */

    // Initialize the DMA stream
    HAL_DMA_DeInit(&DMA1_DMCIHandle);
    if (HAL_DMA_Init(&DMA1_DMCIHandle) != HAL_OK) {
        // Initialization Error
        return -1;
    }
		
		 __HAL_UNLOCK(&DMA1_DMCIHandle);
		
		/*
		__HAL_DMA_ENABLE_IT(&DMA1_DMCIHandle,DMA_IT_TC);    //开启传输完成中断
	  HAL_NVIC_SetPriority(DMA1_Stream1_IRQn,1,1);        //DMA中断优先级
     HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
    */
		if(mem1addr==0)    //开启DMA,不使用双缓冲
    {
        HAL_DMA_Start(&DMA1_DMCIHandle,(uint32_t)&(DCMI->DR),mem0addr,memsize);
			  /*__HAL_DMA_ENABLE_IT(&DMA1_DMCIHandle,DMA_IT_TC);    //开启传输完成中断
        HAL_NVIC_SetPriority(DMA1_Stream1_IRQn,1,1);        //DMA中断优先级
        HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);*/
    }
    else                //使用双缓冲
    {
        HAL_DMAEx_MultiBufferStart(&DMA1_DMCIHandle,(uint32_t)&DCMI->DR,mem0addr,mem1addr,memsize);//开启双缓冲
        __HAL_DMA_ENABLE_IT(&DMA1_DMCIHandle,DMA_IT_TC);    //开启传输完成中断
        HAL_NVIC_SetPriority(DMA1_Stream1_IRQn,1,1);        //DMA中断优先级
        HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
    }    
				
    return 0;
}





//DCMI,启动传输
void DCMI_Start(void)
{  
    //LCD_SetCursor(0,0);  
	  //LCD_WriteRAM_Prepare();		        //开始写入GRAM
    __HAL_DMA_ENABLE(&DMA1_DMCIHandle); //使能DMA
	
	
    DCMI->CR|=DCMI_CR_CAPTURE;          //DCMI捕获使能
	  __HAL_DCMI_CLEAR_FLAG(&DCMIHandle, DCMI_FLAG_VSYNCRI);
	  
}

//DCMI,关闭传输
void DCMI_Stop(void)
{ 
    DCMI->CR&=~(DCMI_CR_CAPTURE);       //关闭捕获
    while(DCMI->CR&0X01);               //等待传输完成
    __HAL_DMA_DISABLE(&DMA1_DMCIHandle);//关闭DMA
} 


//DCMI中断服务函数
void DCMI_IRQHandler(void)
{
    HAL_DCMI_IRQHandler(&DCMIHandle);
}

void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
{
	
	//__HAL_DCMI_CLEAR_FLAG();
	__HAL_DCMI_ENABLE_IT(&DCMIHandle,DCMI_IT_VSYNC);
	
	
}

加上中断优先级之后,就可以进入中断了```

在这里插入图片描述

标签:DMA,HAL,中断,DCMI,Init,DMA1,GPIO,STM32H743
来源: https://blog.csdn.net/Jaken5213/article/details/110494889