STM32F767 + MT9V034 摄像头 不进DMA传输完成中断求助

2019-07-20 04:19发布

不进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();                                         //启动传输         


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。