不进DCMI DMA传输完成中断
检查出现了传输错误中断,哪位大神帮忙分析下!!!
//DCMI DMA配置
//mem0addr:存储器地址0 将要存储摄像头数据的内存地址(也可以是外设地址)
//mem1addr:存储器地址1 当只使用mem0addr的时候,该值必须为0
//memblen:存储器位宽,可以为
MA_MDATAALIGN_BYTE/DMA_MDATAALIGN_HALFWORD/DMA_MDATAALIGN_WORD
//meminc:存储器增长方式,可以为
MA_MINC_ENABLE/DMA_MINC_DISABLE
void DCMI_DMA_Init(u32 mem0addr,u32 mem1addr,u16 memsize,u32 memblen,u32 meminc)
{
__HAL_RCC_DMA2_CLK_ENABLE(); //使能DMA2时钟
__HAL_LINKDMA(&DCMI_Handler,DMA_Handle,DMADMCI_Handler); //将DMA与DCMI联系起来
__HAL_DMA_DISABLE_IT(&DMADMCI_Handler,DMA_IT_TC); //先关闭DMA传输完成中断(否则在使用MCU屏的时候会出现花屏的情况)
DMADMCI_Handler.Instance=DMA2_Stream1; //DMA2数据流1
DMADMCI_Handler.Init.Channel=DMA_CHANNEL_1; //通道1
DMADMCI_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到存储器
DMADMCI_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
DMADMCI_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
DMADMCI_Handler.Init.PeriphDataAlignment=DMA_MDATAALIGN_WORD; //外设数据长度:32位
DMADMCI_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD; //存储器数据长度:8/16/32位
DMADMCI_Handler.Init.Mode=DMA_CIRCULAR; //使用循环模式
DMADMCI_Handler.Init.Priority=DMA_PRIORITY_HIGH; //高优先级
DMADMCI_Handler.Init.FIFOMode=DMA_FIFOMODE_ENABLE; //使能FIFO
DMADMCI_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL; //使用1/2的FIFO
DMADMCI_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器突发传输
DMADMCI_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
HAL_DMA_DeInit(&DMADMCI_Handler); //先清除以前的设置
HAL_DMA_Init(&DMADMCI_Handler); //初始化DMA
//在开启DMA之前先使用__HAL_UNLOCK()解锁一次DMA,因为HAL_DMA_Statrt()HAL_DMAEx_MultiBufferStart()
//这两个函数一开始要先使用__HAL_LOCK()锁定DMA,而函数__HAL_LOCK()会判断当前的DMA状态是否为锁定状态,如果是
//锁定状态的话就直接返回HAL_BUSY,这样会导致函数HAL_DMA_Statrt()和HAL_DMAEx_MultiBufferStart()后续的DMA配置
//程序直接被跳过!DMA也就不能正常工作,为了避免这种现象,所以在启动DMA之前先调用__HAL_UNLOC()先解锁一次DMA。
__HAL_UNLOCK(&DMADMCI_Handler);
if(mem1addr==0) //开启DMA,不使用双缓冲
{
HAL_DMA_Start(&DMADMCI_Handler,(u32)&DCMI->DR,mem0addr,memsize);
}
else //使用双缓冲
{
HAL_DMAEx_MultiBufferStart(&DMADMCI_Handler,(u32)&DCMI->DR,mem0addr,mem1addr,memsize);//开启双缓冲
__HAL_DMA_ENABLE_IT(&DMADMCI_Handler,DMA_IT_TC); //开启传输完成中断
HAL_NVIC_SetPriority(DMA2_Stream1_IRQn,0,0); //DMA中断优先级
HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
}
}
void (*dcmi_rx_callback)(void);//DCMI DMA接收回调函数
//DMA2数据流1中断服务函数
void DMA2_Stream1_IRQHandler(void)
{
if(__HAL_DMA_GET_FLAG(&DMADMCI_Handler,DMA_FLAG_TCIF1_5)!=RESET)//DMA传输完成
{
__HAL_DMA_CLEAR_FLAG(&DMADMCI_Handler,DMA_FLAG_TCIF1_5);//清除DMA传输完成中断标志位
printf("DMA中断传输完成
");
dcmi_rx_callback(); //执行摄像头接收回调函数,读取数据等操作在这里面处理
SCB_CleanInvalidateDCache(); //清除无效的D-Cache
}
if(__HAL_DMA_GET_FLAG(&DMADMCI_Handler,DMA_FLAG_DMEIF1_5))
{
__HAL_DMA_CLEAR_FLAG(&DMADMCI_Handler,DMA_FLAG_DMEIF1_5);//清除DMA传输完成中断标志位
printf("DMA中断 DMA_FLAG_DMEIF1_5
");
}
if(__HAL_DMA_GET_FLAG(&DMADMCI_Handler,DMA_FLAG_FEIF1_5))
{
__HAL_DMA_CLEAR_FLAG(&DMADMCI_Handler,DMA_FLAG_FEIF1_5);//清除DMA传输完成中断标志位
printf("DMA中断 DMA_FLAG_FEIF1_5
");
}
if(__HAL_DMA_GET_FLAG(&DMADMCI_Handler,DMA_FLAG_TEIF1_5))//传输错误中断
{
__HAL_DMA_CLEAR_FLAG(&DMADMCI_Handler,DMA_FLAG_TEIF1_5);//清除DMA中断标志位
printf("DMA中断 DMA_FLAG_TEIF1_5
");
}
}
Main函数中配置
DCMI_DMA_Init((u32)dcmi_line_buf[0],(u32)dcmi_line_buf[1],IMAGE_WIDTH_CONTEXT_A,DMA_MINC_ENABLE);//DCMI DMA配置
DCMI_Start(); //启动传输
一周热门 更多>