今天在玩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 configurationDCMIHandle.Instance = DCMI;// VSYNC clock polarityDCMIHandle.Init.VSPolarity = DCMI_VSPOLARITY_LOW; // HSYNC clock polarityDCMIHandle.Init.HSPolarity = DCMI_HSPOLARITY_LOW;// PXCLK clock polarityDCMIHandle.Init.PCKPolarity = DCMI_PCKPOLARITY_RISING;DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Enable Hardware synchronizationDCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME; // Capture rate all framesDCMIHandle.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 bytesDCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD; // IgnoredDCMIHandle.Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received linesDCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD; // Ignored#endif// Associate the DMA handle to the DCMI handleDCMI->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 DCMIHAL_DCMI_DeInit(&DCMIHandle);if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {// Initialization Errorreturn -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 streamHAL_DMA_DeInit(&DMA1_DMCIHandle);if (HAL_DMA_Init(&DMA1_DMCIHandle) != HAL_OK) {// Initialization Errorreturn -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); //使能DMADCMI->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);}
加上中断优先级之后,就可以进入中断了```