定义的变量:
#define USART_DMA_USING?? ??? ?1 #define USART_DMA_IDLE?? ??? ?0 ? ? ? ? //空闲标志
#define USART6_RX_BUF_MAX ? ? ? ? ? 1024 #define USART6_TX_BUF_MAX ? ? ? ? ? 1024
#define UART_QUEUE_BUF_MAX ? ? ? ? ?1024
#define UART_UPPER_QUEUE_MAX ? ? ? ?20 ? ? ? ? ? ?//队列长度
u8 Usart6RxBuf[USART6_RX_BUF_MAX]; u8 Usart6TxBuf[USART6_TX_BUF_MAX];
u16 Usart6RxNum; u16 Usart6TxLen; u16 Usart6RxNum; u8 ?SendingFlagUart;
typedef enum? { ?? ?kUART_QUEUE_IDLE = 0, ? ? ? ? ? ? ?//没有要处理的数据 ?? ?kUART_QUEUE_FLAG, ? ? ? ? ? ? ? ? ?//有要处理的数据 }UART_QUEUE_CMD;
typedef struct ?_usartQueueBuffer { ?? ?u8 ?uartQueueBuf[UART_QUEUE_BUF_MAX]; ? ? ? ?//发送BUF ?? ?u16 uartQueueLen; ? ? ? ? ? ? ? ? ? ? ? ? ? ?//发送数据长度 ? UART_QUEUE_CMD uartQueueCmdFlag; ? ? ? ? ? ? //是否要处理 ?? ? }UsartQueueBuffer;
UsartQueueBuffer ?UsartUpperRxBuf[UART_UPPER_QUEUE_MAX]; ? //发送数据队列 UsartQueueBuffer ?UsartUpperTxBuf[UART_UPPER_QUEUE_MAX]; ? //接收数据队列 u8 ? UsartTxQueueOrder; ? u8 ? UsartRxQueueOrder;
u8 ComUpperRxDataBufRcv[UART_QUEUE_BUF_MAX]; ? //接收数据BUFfalo
1.初始化串口 void UsartInit(void) { ?? ??? ?GPIO_InitTypeDef GPIO_InitStructure; ?? ??? ?USART_InitTypeDef USART_InitStructure; ?? ??? ?//?? ?NVIC_InitTypeDef NVIC_InitStructure;
?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); ?? ??? ??? ?//使能GPIOC时钟 ?? ??? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);?? ??? ??? ?//使能USART6时钟
?? ??? ?//串口6对应引脚复用映射 ?? ??? ?GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6); ?? ??? ?//GPIOC6复用为USART6 ?? ??? ?GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); ?? ??? ?//GPIOC7复用为USART6
?? ??? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; ?? ??? ??? ?//GPIOC6与GPIOC7 ?? ??? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;?? ??? ??? ??? ??? ?//复用功能 ?? ??? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;?? ??? ??? ??? ?//速度50MHz ?? ??? ?GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; ?? ??? ??? ??? ??? ?//推挽复用输出 ?? ??? ?GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; ?? ??? ??? ??? ??? ?//上拉 ?? ??? ?GPIO_Init(GPIOC,&GPIO_InitStructure); ?? ??? ??? ??? ??? ??? ??? ?//初始化PC6,PC7
?? ??? ?/* ?配置串口硬件参数 */ ?? ??? ?USART_InitStructure.USART_BaudRate = 115200;?? ??? ?//波特率设置 ?? ??? ?USART_InitStructure.USART_WordLength = USART_WordLength_8b;?? ??? ?//字长为8位数据格式 ?? ??? ?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(USART6, &USART_InitStructure); ?? ??? ??? ??? ??? ??? ?//初始化串口6
?? ??? ?//?? ?USART_ClearFlag(USART6, USART_FLAG_RXNE); ?? ??? ?//?? ?USART_ClearFlag(USART6, USART_FLAG_TC); ?? ??? ?//?? ?USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);?? ??? ??? ??? ??? ?// 使能接收中断?? ? ?? ??? ?//用于判断是否接收完一包数据. ?? ??? ?USART_ITConfig(USART6, USART_IT_IDLE, ENABLE);?? ??? ??? ??? ??? ?// 使能串口空闲中断
?? ??? ?USART_Cmd(USART6, ENABLE); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// 串口使能 ?? ??? ?// 初始化相应串口接收和发送缓存 ?? ??? ?DriveUartBuffClearInit(Usart6RxBuf,USART6_RX_BUF_MAX);?? ??? ??? ??? ? ?? ??? ?DriveUartBuffClearInit(Usart6TxBuf,USART6_TX_BUF_MAX);?
?? ??? ?NVIC_EnableIRQ(USART6_IRQn);?? ??? ??? ??? ??? ??? ??? ??? ??? ?// 使能串口中断 ?? ??? ?USART_DMACmd(USART6,USART_DMAReq_Tx,ENABLE); ?//使能串口1的DMA发送 ?? ?? ??? ?USART_DMACmd(USART6,USART_DMAReq_Rx,ENABLE); ?//使能串口1的DMA接收?
?? ??? ?// 串口DMA初始化 ?? ??? ?dma2_Stream2_init(); ?? ??? ?dma2_Stream6_init(); }
2.初始化发送DMA
void dma2_Stream6_init(void) { ? ?? ??? ?DMA_InitTypeDef ?DMA_InitStructure; ?? ??? ?NVIC_InitTypeDef NVIC_InitStructure;
?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
?? ??? ?while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE) ?? ??? ?{ ?? ??? ?; ?? ??? ?}//等待DMA2_Stream6可配置?
?? ??? ?DMA_DeInit(DMA2_Stream6);? ?? ??? ?/* 配置 DMA Stream */ ?? ??? ?DMA_InitStructure.DMA_Channel = DMA_Channel_5; ?//通道4 ?? ??? ?DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART6->DR; ? ? ? ? ? //DMA 对应的外设USART4->DR地址 ?? ??? ?DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Usart6TxBuf; ? ? ? // 内存存储基地址
?? ??? ?DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式 ?? ??? ?DMA_InitStructure.DMA_BufferSize = USART6_TX_BUF_MAX;//数据传输量 ?? ??? ?DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式 ?? ??? ?DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式 ?? ??? ?DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位 ?? ??? ?DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度 8位 ?? ??? ?DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 循环模式 ?? ??? ?DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级 ?? ??? ?DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO模式不开启? ?? ??? ?DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;?? ? ?? ??? ?DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输 ?? ??? ?DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输 ?? ??? ?DMA_Init(DMA2_Stream6, &DMA_InitStructure);//初始化DMA Stream
?? ??? ?//?? ?DMA_Cmd(DMA2_Stream6, ENABLE); ? ? ? ? ? ? ? ? ?/* DMA2_Stream6 enable */ // 在发送的时候才开启DMA ?? ??? ?//DMA NVIC ? ?? ??? ?NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn; ? ? ?? ??? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ? ?? ??? ?NVIC_Init(&NVIC_InitStructure); ? ?? ??? ?DMA_ITConfig(DMA2_Stream6,DMA_IT_TC,ENABLE); }
3.初始化接收DMA
void dma2_Stream2_init(void) { ? ?? ??? ?DMA_InitTypeDef ?DMA_InitStructure; ?? ??? ?NVIC_InitTypeDef NVIC_InitStructure;
?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA1时钟使能
?? ??? ?while (DMA_GetCmdStatus(DMA2_Stream2) != DISABLE) ?? ??? ?{ ?? ??? ?; ?? ??? ?}//等待DMA2_Stream2可配置?
?? ??? ?DMA_DeInit(DMA2_Stream2);? ?? ??? ?/* 配置 DMA Stream */ ?? ??? ?DMA_InitStructure.DMA_Channel = DMA_Channel_5; ?//通道4 ?? ??? ?DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART6->DR; ? ? ? ? ? //DMA 对应的外设USART1->DR地址 ?? ??? ?DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Usart6RxBuf; ? ? ? // 内存存储基地址
?? ??? ?DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;//外设到存储器模式 ?? ??? ?DMA_InitStructure.DMA_BufferSize = USART6_RX_BUF_MAX;//数据传输量 ?? ??? ?DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式 ?? ??? ?DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式 ?? ??? ?DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位 ?? ??? ?DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度 8位 ?? ??? ?DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 循环模式 ?? ??? ?DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//高优先级 ?? ??? ?DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO模式不开启 ? ?? ??? ?DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; ? ? ?? ??? ?DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输 ?? ??? ?DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输 ?? ??? ?DMA_Init(DMA2_Stream2, &DMA_InitStructure);//初始化DMA Stream
?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? ? ? ? ? ? ? ?/* DMA2_Stream2 enable */ ?? ??? ?//DMA NVIC ? ?? ??? ?NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn; ? ? ?? ??? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ? ?? ??? ?NVIC_Init(&NVIC_InitStructure); ? ?? ??? ?DMA_ITConfig(DMA2_Stream2,DMA_IT_TC,ENABLE); }
4.中断处理
//串口6 中断函数 void USART6_IRQHandler(void) {?? ? ?? ?u8 clear; ?? ?//用于判断是否接收完一包数据. ?? ?if (USART_GetITStatus(USART6, USART_IT_IDLE)==SET) ?? ?{ ?? ??? ?USART_ClearITPendingBit(USART6, USART_IT_IDLE); ?? ??? ?clear = USART6->SR; ?? ??? ?clear = USART6->DR; ?? ??? ?clear = clear;//无任何作用 去除编译告警 ?? ??? ? ?? ??? ?DMA_Cmd(DMA2_Stream2, DISABLE); //关闭DMA,防止处理期间有数据 ?? ??? ?Usart6RxNum = USART6_RX_BUF_MAX - DMA_GetCurrDataCounter(DMA2_Stream2); ?? ??? ? ?? ??? ?UsartUpperRxBuf[UsartRxQueueOrder].uartQueueLen = Usart6RxNum; ?? ??? ?DriveUsartGetRecvData(UsartUpperRxBuf[UsartRxQueueOrder].uartQueueBuf,Usart6RxNum); ?? ??? ?UsartUpperRxBuf[UsartRxQueueOrder].uartQueueCmdFlag = USART_DMA_USING; ? ? UsartRxQueueOrder++; ?? ??? ?if(UsartRxQueueOrder >= UART_UPPER_QUEUE_MAX) ?? ??? ?{ ?? ??? ??? ?UsartRxQueueOrder = 0; ?? ??? ?} ?? ??? ? ?? ??? ?DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2);//清除DMA1_Steam0传输完成标志 ?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? //打开DMA,?? ??? ? ?? ?} ?? ? ?? ?if(USART_GetFlagStatus(USART6,USART_FLAG_ORE) == SET) //溢出? ?? ?{ ?? ??? ?USART_ClearFlag(USART6,USART_FLAG_ORE); //读SR ?? ?? ??? ?USART_ReceiveData(USART6); //读DR ?? ??? ? ?? ?}? ?? ? }
? void DMA2_Stream2_IRQHandler(void) { ?? ?//清除标志 ?? ?if(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2)!=RESET)//等待DMA2_Steam2传输完成 ?? ?{? ?? ??? ?DMA_Cmd(DMA2_Stream2, DISABLE); //关闭DMA,防止处理期间有数据 ?? ??? ?Usart6RxNum = 0;?? ??? ? ?? ??? ?DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2);//清除DMA1_Steam1传输完成标志 ?? ??? ?DMA_SetCurrDataCounter(DMA2_Stream2, USART6_RX_BUF_MAX); ?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? //打开DMA, ?? ?} }
//串口6发送完成中断 void DMA2_Stream6_IRQHandler(void) { ?? ?//清除标志 ?? ?if(DMA_GetFlagStatus(DMA2_Stream6,DMA_FLAG_TCIF6)!=RESET)//等待DMA1_Steam3传输完成 ?? ?{? ?? ??? ?SendingFlagUart = USART_DMA_IDLE; ?? ??? ?DMA_ClearFlag(DMA2_Stream6,DMA_FLAG_TCIF6);//清除DMA1_Steam3传输完成标志 ?? ?} } ?
5.接收数据处理
void ComUpperRxDataHandle(void) { ?? ?static u8 rxUpperOrder = 0; ?? ?if(UsartRxQueueOrder != rxUpperOrder)//接受一包数据中断标志位 ?? ?{ ?? ??? ?memcpy(ComUpperRxDataBufRcv,UsartUpperRxBuf[rxUpperOrder].uartQueueBuf,UsartUpperRxBuf[rxUpperOrder].uartQueueLen); ?? ??? ?memset(UsartUpperRxBuf[rxUpperOrder].uartQueueBuf, 0, UsartUpperRxBuf[rxUpperOrder].uartQueueLen); ?? ??? ?UsartUpperRxBuf[rxUpperOrder].uartQueueLen = 0; ?? ??? ?UsartUpperRxBuf[rxUpperOrder].uartQueueCmdFlag = USART_DMA_IDLE; ?? ??? ?rxUpperOrder++; ?? ??? ?if(rxUpperOrder >= UART_UPPER_QUEUE_MAX) ?? ??? ?{ ?? ??? ??? ?rxUpperOrder = 0; ?? ??? ?} ?? ? ?//在这里对ComUpperRxDataBufRcv进行解析 ?? ??? ?if((ComUpperRxDataBufRcv[0] == 0xAA) && (ComUpperRxDataBufRcv[0] == 0x55)) ?? ??? ?{ ?? ??? ? ?? ??? ?} ?? ?} }
6.main函数
int main(void) {? ? u8 i; ?? ?UsartInit(); ?? ?? ?//测试发送数据,发送10包数据,每包数据从0~19 ?? ?for(i = 0; i < 20; i++) ?? ?{ ?? ??? ?sendTest[i] = i; ?? ?} ?? ? ?? ?for(i = 0 ; i < 10 ; i++) ?? ?{ ?? ??? ?UsartSendData(sendTest,20); ?? ?} ?? ? ?? ?while(1) ?? ?{?? ? ?? ??? ?Usart6_SendData(); ?? ??? ?ComUpperRxDataHandle(); ?? ?} }
7.源程序下载地址
源代码程序https://download.csdn.net/download/u011671172/31499254https://download.csdn.net/download/u011671172/31499254
|