STM32F407串口DMA接收完成中断无法进入问题,求助,堵了几天了。。。谢谢

2019-07-20 01:18发布

自己写的初始化框架,代码看下就行了(建议复制到notpad++看),或者有实验成功的大哥们分享、指点下。
初始化步骤如下(代码亦如下,寄存器初始化都是库函数,不是直接操作寄存器):
0.DMA中断优先级配置
1.串口《全局变量》配置
2.DMA《全局变量》+DMA中断类型+中断通道配置

3.串口《寄存器》配置(依据串口全局变量)(USART_Init)
4.串口DMA外设、内存地址+传输方向全局变量配置
5.DMA《寄存器》配置(依据DMA全局变量)(DMA_Init)
6.清除DMA中断标志(DMA_ClearFlag)+配置使能DMA中断类型(DMA_ITConfig)
7.使能串口接收DMA(USART_DMACmd)
8.开启DMA接收(msp_Dma_Enable)
9.DMA中断入口函数(DMA1_Stream2_IRQHandler)

说明:因为初始化框架是想着兼容多款芯片而写的,配置都OK,能通过串口DMA接收到完整的一帧数据(DMA_Mode_Normal),
         但是就是不能进入DMA1_Stream2_IRQHandler中断,而我需要接收完一帧数据后能进入中断,请大家帮帮忙看下,谢谢。
         (DMA所有配置参见g_sGpsUart.RxDma....)(建议复制到notpad++看)

[mw_shl_code=c,true]/*NVIC_NVIC_PriorityGroup_2*/
/*GPS串口DMA接收完成中断*/
NVIC_InitStructure.NVIC_IRQChannel                   = g_sGpsM8N.UartMaster->RxDma.NVIC_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;    /*抢占优先级*/
NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;    /*响应优先级*/
NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
NVIC_Init(&NVIC_InitStructure);       

/*串口DMA参数配置*/
if (g_sGpsUart.RxMode == MSP_UART_DMA)
{
        /*配置接收DMA*/
        g_sGpsUart.RxDma.Stream         = DMA1_Stream2;                       /*DMA流*/
        g_sGpsUart.RxDma.Channel        = DMA_Channel_4;                       /*DMA通道*/
        g_sGpsUart.RxDma.RCC_Periph_DMA = RCC_AHB1Periph_DMA1;         /*DMA时钟*/
        g_sGpsUart.RxDma.BuffSize             = GPS_M8N_RX_BUFF_LENTH;       /*buff(缓冲区)大小*/
        g_sGpsUart.RxDma.PerAlignByte   = DMA_PeripheralDataSize_Byte; /*1字节对齐*/
        g_sGpsUart.RxDma.MemAlignByte   = DMA_MemoryDataSize_Byte;     /*1字节对齐*/
        g_sGpsUart.RxDma.Mode           = DMA_Mode_Normal;                              /*单次接收*/
        g_sGpsUart.RxDma.Priority       = DMA_Priority_High;                   /*优先级*/
        g_sGpsUart.RxDma.dmaFlag        = DMA_IT_TCIF2;                               /*Stream传输完毕标志*/
        g_sGpsUart.RxDma.dmaIT                    = DMA_IT_ENABLE;                           /*启用DMA中断*/
       
        /*是否使用DMA接收中断,若使用就选择中断类型,并设置中断请求通道*/
        if (g_sGpsUart.RxDma.dmaIT == DMA_IT_ENABLE)
        {
                g_sGpsUart.RxDma.ITType          = DMA_IT_TC;
                g_sGpsUart.RxDma.NVIC_IRQChannel = DMA1_Stream2_IRQn;                               
        }
       
        /*使能接收DMA时钟*/
        periphRccTree = SYS_RCC_AHB1;  /*设定DMA时钟树*/
        sys_Peripheral_RCC_Init(periphRccTree, g_sGpsUart.RxDma.RCC_Periph_DMA, ENABLE);
}

/*配置UART接收工作模式*/
if (uart->RxMode == MSP_UART_DMA)        /*配置DMA*/
{
        /*接收DMA配置及初始化*/
        uart->RxDma.PerBaseAddr = (u32)&(uart->Uart->DR);                /*外设目标地址*/
        uart->RxDma.MemBaseAddr = (u32)(uart->pRxBuff);                        /*内存目标地址*/
        uart->RxDma.Direction   = DMA_DIR_PeripheralToMemory;        /*外设到内存*/
       
        /*接收DMA初始化*/
        msp_Dma_Init(&(uart->RxDma));
       
        /*默认使能串口接收DMA*/
        USART_DMACmd(uart->Uart, USART_DMAReq_Rx, ENABLE);       
       
        /*默认开启DMA接收*/
        msp_Dma_Enable(&(uart->RxDma));
}

/*DMA初始化*/
void msp_Dma_Init(Msp_Dma * msp_Dma)
{
        DMA_InitTypeDef DMA_InitStruct;
       
        DMA_DeInit(msp_Dma->Stream);        /*将DMA_Stream寄存器设置为缺省值*/
       
        while (DMA_GetCmdStatus(msp_Dma->Stream) != DISABLE){} /*等待DMA可配置*/
       
        DMA_InitStruct.DMA_Channel                        = msp_Dma->Channel;
        DMA_InitStruct.DMA_PeripheralBaseAddr  = msp_Dma->PerBaseAddr;
        DMA_InitStruct.DMA_Memory0BaseAddr     = msp_Dma->MemBaseAddr;
        DMA_InitStruct.DMA_DIR                 = msp_Dma->Direction;
        DMA_InitStruct.DMA_BufferSize          = msp_Dma->BuffSize;
        DMA_InitStruct.DMA_PeripheralInc       = DMA_PeripheralInc_Disable;        /*禁止外设地址增长*/
        DMA_InitStruct.DMA_MemoryInc           = DMA_MemoryInc_Enable;                /*使能内存地址增长*/
        DMA_InitStruct.DMA_PeripheralDataSize  = msp_Dma->PerAlignByte;
        DMA_InitStruct.DMA_MemoryDataSize      = msp_Dma->MemAlignByte;
        DMA_InitStruct.DMA_Mode                = msp_Dma->Mode;
        DMA_InitStruct.DMA_Priority            = msp_Dma->Priority;
        DMA_InitStruct.DMA_FIFOMode                    = DMA_FIFOMode_Disable;       /*禁用Fifo*/  
        DMA_InitStruct.DMA_FIFOThreshold       = DMA_FIFOThreshold_Full;         /*满*/
        DMA_InitStruct.DMA_MemoryBurst         = DMA_MemoryBurst_Single;     /*存储器突发单次传输*/
        DMA_InitStruct.DMA_PeripheralBurst     = DMA_PeripheralBurst_Single; /*外设突发单次传输*/               
       
        DMA_Init(msp_Dma->Stream, &DMA_InitStruct);
               
        /*判断是否启用DMA中断,并配置对应对应中断*/
        if (msp_Dma->dmaIT == DMA_IT_ENABLE)
        {
                /*预清除中断标志*/
                DMA_ClearFlag(msp_Dma->Stream, msp_Dma->ITType);
               
                /*配置使能中断*/
                DMA_ITConfig(msp_Dma->Stream, msp_Dma->ITType, ENABLE);                       
        }               
}

/*DMA使能*/
void msp_Dma_Enable(Msp_Dma * msp_Dma)
{
        /*关闭DMA指示通道*/
        DMA_Cmd(msp_Dma->Stream, DISABLE);
       
        /*确保DMA可以被设置*/
        while(DMA_GetCmdStatus(msp_Dma->Stream) != DISABLE){}       
       
        /*DMA通道的数据传输量设置*/
        DMA_SetCurrDataCounter(msp_Dma->Stream, msp_Dma->BuffSize);
       
        /*使能DMA指示通道*/
        DMA_Cmd(msp_Dma->Stream, ENABLE);       
}

/*中断入口函数*/
/*1.DMA1_Stream2:GPS_RX*/
void DMA1_Stream2_IRQHandler(void)
{
        if (DMA_GetITStatus(g_sGpsM8N.UartMaster->RxDma.Stream, g_sGpsM8N.UartMaster->RxDma.dmaFlag) == SET)
        {
                /*GPS数据更新完毕标志*/
                g_sGpsM8N.DATA_STATUS = GPS_DATA_NEW;
               
                /*失能串口DMA*/
                USART_DMACmd(g_sGpsM8N.UartMaster->Uart, USART_DMAReq_Rx, DISABLE);
               
                /*失能DMA传输*/
                msp_Dma_Disable(&g_sGpsM8N.UartMaster->RxDma);
               
                /*清除中断标志位*/
                DMA_ClearITPendingBit(g_sGpsM8N.UartMaster->RxDma.Stream, g_sGpsM8N.UartMaster->RxDma.dmaFlag);
        }
}[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。