今天在玩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);
}
加上中断优先级之后,就可以进入中断了```