DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。
USART3使用DMA 通道3。
usart3配置
UART3 RX3--->PB.11 TX3 --->PB.10
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); //使能UART3所在GPIOB的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口时钟配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 ULTR_EN-->PB.10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化PB.10
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART3, &USART_InitStructure);
//Usart3 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
USART_ITConfig(USART3,USART_IT_TC,DISABLE); //关闭发送中断
USART_ITConfig(USART3,USART_IT_RXNE,DISABLE);//关闭接收中断
USART_ITConfig(USART3,USART_IT_IDLE,ENABLE); //开启总线空闲中断
USART_Cmd(USART3, ENABLE); // 使能 USART3
DMA配置
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA1时钟
DMA_DeInit(DMA1_Channel3); //初始化DMA1通道3 串口3接收通道
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004804; //串口3接收数据的地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)GPS_Uart_Rcv_Buf; //数据存放的复制
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传送方向 串口3作为数据源
DMA_InitStructure.DMA_BufferSize = GPS_Rev_Buf_Size; //接收数据个数
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外围设备 串口3 地址不递增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // DMA存储地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外围设备 串口3 数据宽度 8bits
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //DMA存储 数据宽度 8bits
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环获取数据
//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //串口3通道优先为中等
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //关闭内存到内存
DMA_Init(DMA1_Channel3, &DMA_InitStructure);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE); //使能串口3 DMA功能
DMA_Cmd(DMA1_Channel3, ENABLE);
USART3中断
/*--------------
DMA接收一次数据后停止工作并触发进入串口总线中断
-------------*/
//DMA mode 设置为DMA_Mode_Normal
//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //接收一次DMA数据停止工作
//DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
void USART3_IRQHandler(void)
{
u8 i = 0;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //串口3 总线空闲
{
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //清除标记位
if(GPS_Uart_Rcv_Buf[0]!= '$') //出错
{
i = 0;
}
else//完成获取数据
{
i = 0;
//标记
}
}
}
/*------------------
DMA连续接收数据并持续触发串口总线中断
-----------------*/
//DMA mode 设置为DMA_Mode_Circular
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环获取数据
void USART3_IRQHandler(void)
{
u8 i = 0;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //串口3 总线空闲
{
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //清除标记位
if(GPS_Uart_Rcv_Buf[0]!= '$') //出错
{
i = 0;
}
else//完成获取数据
{
i = 0;
//标记
}
}
}
/*------------------
DMA连续接收数据并持续触发串口总线中断。在接收一次后关闭DMA功能
-----------------*/
//DMA mode 设置为DMA_Mode_Circular
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环获取数据
void USART3_IRQHandler(void)
{
u8 i = 0;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //串口3 总线空闲
{
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //清除标记位
/*----------------------------------------------------------*/
DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA1通道3
/*----------------------------------------------------------*/
if(GPS_Uart_Rcv_Buf[0]!= '$') //出错
{
i = 0;
}
else//完成获取数据
{
i = 0;
//标记
}
}
}
/*------------------
DMA连续接收数据并持续触发串口总线中断。人为控制DMA接收频率
-----------------*/
//DMA mode 设置为DMA_Mode_Circular
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环获取数据
void USART3_IRQHandler(void)
{
u8 i = 0;
if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) //串口3 总线空闲
{
USART_ClearITPendingBit(USART3, USART_IT_IDLE); //清除标记位
DMA_Cmd(DMA1_Channel3, DISABLE);//关闭DMA1通道3
if(GPS_Uart_Rcv_Buf[0]!= '$') //出错
{
i = 0;
}
else//完成获取数据
{
i = 0;
//标记
}
DMA_SetCurrDataCounter(DMA1_Channel3,GPS_Rev_Buf_Size); //接收数据个数
DMA_Cmd(DMA1_Channel3, ENABLE); //开启DMA1通道3
}
}