1.背景与术语
1.1 DMA(Direct Memory Access,直接存储器访问)是独立于CPU的高速数据搬运外设,可在“外设↔存储器”或“存储器↔存储器”之间完成批量传输,零CPU介入。
1.2本文以“USART3-RX接收60 GHz毫米波雷达串口数据”为示例,完整展示DMA1-Ch3的配置流程及代码规范。
2.国民技术N32G457QEL7硬件资源
2.1芯片型号:N32G457QEL7
2.2外设:USART3(RX,PB11),DMA1 Channel3
2.3时钟树:
•DMA1位于AHB总线
•USART3位于APB1总线
•PB11需开启GPIOB+AFIO时钟
2.4DMA的通道映射图和对应关系表如下
2.41 DMA1的通道映射图和对应关系表


2.42 DMA2的通道映射图和对应关系表


3.DMA的使用
在使用DMA之前需要确认是通过DMA发送数据还是通过DMA进行接收数据,以及确认使用对应外设的接口。
3.1 DMA的软件实现
初始化串口三使用的RX接口,及IO口的配置,配置源码如下:
void RCC_Configuration_USART3(void)
{
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1,ENABLE);//开启DMA1的时钟
GPIO_APBxClkCmd(USART3_GPIO_CLK|RCC_APB2_PERIPH_AFIO,ENABLE);//开启串口的时钟和其对应的复用功能
USART3_APBxClkCmd(USART3_CLK,ENABLE);开启串口三对应IO口对应的端口时钟(这里只是重新定义了函数,名称、时钟名称,可自己查询对应的时钟树进行配置)
}
void GPIO_Configuration_USART3(void)//配置串口三的对应io口的工作模式
{
GPIO_InitType GPIO_InitStructure;
GPIO_InitStructure.Pin=USART3_RxPin;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入模式
GPIO_InitPeripheral(USART3_GPIO,&GPIO_InitStructure);
}
void USART3_configure(u32 bound)//配置串口三的结构体和对应的DMA接收配置
{
USART_InitType USART_InitStructure;
RCC_Configuration_USART3();
NVIC_Configuration_USART3();
GPIO_Configuration_USART3();
DMA_USART3RX_Configuration();
USART_InitStructure.BaudRate=bound;
USART_InitStructure.WordLength=USART_WL_8B;
USART_InitStructure.StopBits=USART_STPB_1;
USART_InitStructure.Parity=USART_PE_NO;
USART_InitStructure.HardwareFlowControl=USART_HFCTRL_NONE;
USART_InitStructure.Mode=USART_MODE_RX|USART_MODE_TX;
USART_Init(USART3,&USART_InitStructure);
//USART_ConfigInt(USART3,USART_INT_RXDNE,ENABLE);
//USART_ConfigInt(USART3,USART_INT_IDLEF,ENABLE);
USART_EnableDMA(USART3,USART_DMAREQ_RX,ENABLE);
//DMA_ClrIntPendingBit(DMA1_INT_TXC3,DMA1);//清除传输完成中断标志位
//DMA_ConfigInt(USART3_Rx_DMA_Channel,DMA_INT_TXC,ENABLE);//DMA搬运完成中断使能
DMA_EnableChannel(USART3_Rx_DMA_Channel,ENABLE);
USART_Enable(USART3,ENABLE);
}
//配置DMA串口三RX引脚的DMA配置,以及DMA的中断配置
void DMA_USART3RX_Configuration(void)
{
DMA_InitType DMA_InitStructure;
NVIC_InitType NVIC_InitStructure;
DMA_DeInit(USART3_Rx_DMA_Channel);
DMA_InitStructure.PeriphAddr=USART3_DR_Base;//数据来自USART3的DR寄存器
DMA_InitStructure.MemAddr=(uint32_t)radar60GData.radar60GRxBuf;//将DMA接收到的数据存放至60G的接收缓冲区中
DMA_InitStructure.Direction=DMA_DIR_PERIPH_SRC;//外设是数据源
DMA_InitStructure.BufSize=RADAR60G_RXBUF_SIZE;//数据缓冲区的大小
DMA_InitStructure.PeriphInc=DMA_PERIPH_INC_DISABLE;//外设地址不递增因为数据是由外设到缓冲区
DMA_InitStructure.DMA_MemoryInc=DMA_MEM_INC_ENABLE;//启用内存地址递增以便存储雷达数据
DMA_InitStructure.PeriphDataSize=DMA_PERIPH_DATA_SIZE_BYTE;//设置外设数据大小0
DMA_InitStructure.MemDataSize=DMA_MemoryDataSize_Byte;//内存数据的大小为这么多个字节
DMA_InitStructure.CircularMode=DMA_MODE_CIRCULAR;//循环模式
DMA_InitStructure.Priority=DMA_PRIORITY_VERY_HIGH;//设置DMA的优先级
DMA_InitStructure.Mem2Mem=DMA_M2M_DISABLE;//禁用内存到内存传输
DMA_Init(USART3_Rx_DMA_Channel,&DMA_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);//设置中断分组
NVIC_InitStructure.NVIC_IRQChannel=USART3_RX_DMA_IRQN;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
以上既是N32G457QEL7的串口三RX引脚DMA接收毫米波雷达数据的软件配置。
关键点与常见错误
1.循环模式(Circular)下,DMA搬运完成后自动重载计数器,无需手动重启。
2.若改为普通模式(DMA_MODE_NORMAL),必须在TC中断里重新设置BufSize并再次EnableChannel,否则DMA停止。
3.PeriphAddr必须是固定的外设寄存器地址;MemAddr必须指向有效SRAM区域,且不能位于栈上。
4.若打开AFIO重映射,务必确认GPIO_RMP_USART3已使能,否则USART3_RX仍映射到默认引脚。
通过DMA1_Channel3与USART3_RX的组合,可在零CPU干预的情况下稳定接收毫米波雷达的高速串口数据。上述代码已在N32G457QEL7-EVAL板验证通过,波特率921600 bps,数据无丢包,CPU占用率<1%。
如需了解国民技术N32G457REL7的相关资料,可以联系国民技术代理商海凌微销售-江小姐,电话:18126156267。
如需了解国民技术N32G457REL7的相关资料,可以联系国民技术代理商海凌微销售-江小姐,电话:18126156267。
