自己写的初始化框架,代码看下就行了(建议复制到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]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
我的问题解决了,你啥问题?
一周热门 更多>