.h文件
/************************************************************* File Name: DrvUartr.h
* File Instruction: 串口驱动头文件
* File User: Phyllis
* File TIME: 2022-02-19
* File Version: V1.0
************************************************************/#ifndef __DrvUart_H
#define __DrvUart_H/************************define******************************/// UART1
#define USART1_TX_GPIO_PORT GPIOA
#define USART1_TX_GPIO_PIN GPIO_PIN_9 #define USART1_RX_GPIO_PORT GPIOA
#define USART1_RX_GPIO_PIN GPIO_PIN_10 // UART2
#define USART2_TX_GPIO_PORT GPIOA
#define USART2_TX_GPIO_PIN GPIO_PIN_2 #define USART2_RX_GPIO_PORT GPIOA
#define USART2_RX_GPIO_PIN GPIO_PIN_3 // UART3
#define USART3_TX_GPIO_PORT GPIOB
#define USART3_TX_GPIO_PIN GPIO_PIN_10 #define USART3_RX_GPIO_PORT GPIOB
#define USART3_RX_GPIO_PIN GPIO_PIN_11 // Priority
#define USART1_Priority 0
#define USART1_SubPriority 1#define USART2_Priority 0
#define USART2_SubPriority 2#define USART2_dma_Priority 0
#define USART2_dma_SubPriority 2#define USART3_Priority 0
#define USART3_SubPriority 3#define USART3_dma_Priority 0
#define USART3_dma_SubPriority 3// BoundRate
#define USART1_Bound (INT32U)(115200)
#define USART2_Bound (INT32U)(115200)
#define USART3_Bound (INT32U)(115200)/************************struct******************************/
typedef enum
{UartPort1,UartPort2,UartPort3,UartPortAll,}UartPort;/************************function******************************/
void DrvUart_Init(UartPort Port,INT32U Bound);
void DrvUart_SendByte(UartPort Port,INT8U byte);
void DrvUart_SendString(UartPort Port,INT8U *str,INT8U len);
void uart2_dma_tx_data(u8 *buff,u16 data_len);
void uart3_dma_tx_data(u8 *buff,u16 data_len);#endif
.c文件
/************************************************************* File Name: DrvUart.c
* File Instruction: 该文件为串口驱动文件
* File User: Phyllis
* File TIME: 2022-02-19
* File Version: V1.0
************************************************************/
#include "include.h"#define uart2_tx_len 128
#define uart3_tx_len 128void DMA_CH2_Init(u32 cpar);USART_Module* UartDef[UartPortAll] = { USART1,USART2,USART3};
GPIO_Module* UartTxPort[UartPortAll] = {USART1_TX_GPIO_PORT,USART2_TX_GPIO_PORT,USART3_TX_GPIO_PORT};
GPIO_Module* UartRxPort[UartPortAll] = {USART1_RX_GPIO_PORT,USART2_RX_GPIO_PORT,USART3_RX_GPIO_PORT};
const INT32U UartTxPin[UartPortAll] = {USART1_TX_GPIO_PIN,USART2_TX_GPIO_PIN,USART3_TX_GPIO_PIN};
const INT32U UartRxPin[UartPortAll] = {USART1_RX_GPIO_PIN,USART2_RX_GPIO_PIN,USART3_RX_GPIO_PIN};uint8_t uart2_dma_tx[uart2_tx_len];//串口3DMA发送
uint8_t uart3_dma_tx[uart3_tx_len];//串口3DMA发送uint8_t uart2_tx_flag = 0;//发送标志位
uint8_t uart3_tx_flag = 0;//发送标志位/* retarget the C library printf function to the usart */
int fputc(int ch, FILE *f)
{USART_SendData(USART1, (uint8_t)ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TXDE) == RESET);return ch;
}
/*
*********************************************************************************************************
* 函 数 名: DrvUart_Init
* 功能说明: 串口函数初始化
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void DrvUart_Init(UartPort Port,INT32U Bound)
{GPIO_InitType GPIO_InitStructure;NVIC_InitType NVIC_InitStructure;USART_InitType USART_InitStructure;DMA_InitType DMA_InitStructure;GPIO_InitStruct(&GPIO_InitStructure);/* Configure USART Tx as alternate function push-pull */GPIO_InitStructure.Pin = UartTxPin[Port]; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitPeripheral(UartTxPort[Port], &GPIO_InitStructure);/* Configure USART Rx as alternate function push-pull and pull-up */GPIO_InitStructure.Pin = UartRxPin[Port];GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitPeripheral(UartRxPort[Port], &GPIO_InitStructure);/* Configure the NVIC Preemption Priority Bits */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);switch( Port){case UartPort1:NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART1_Priority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = USART1_SubPriority;break;case UartPort2:NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART2_Priority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = USART2_SubPriority;break;case UartPort3:NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART3_Priority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = USART3_SubPriority;break;default:break;}NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);USART_StructInit(&USART_InitStructure);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(UartDef[Port], &USART_InitStructure);USART_ConfigInt(UartDef[Port], USART_INT_RXDNE, ENABLE);if( Port> UartPort1)USART_ConfigInt(UartDef[Port], USART_INT_IDLEF, ENABLE);if(Port == UartPort2){//打开串口2的DMA发送 tx-DMA1-Channel7DMA_DeInit(DMA1_CH7);DMA_InitStructure.PeriphAddr = (INT32U)(&USART2->DAT);DMA_InitStructure.MemAddr = (INT32U)uart2_dma_tx;DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;DMA_InitStructure.BufSize = uart2_tx_len;DMA_InitStructure.PeriphInc = DMA_MEM_INC_DISABLE;DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;DMA_Init(DMA1_CH7, &DMA_InitStructure);DMA_EnableChannel(DMA1_CH7,DISABLE);NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART2_dma_Priority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = USART2_dma_SubPriority;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);DMA_ConfigInt(DMA1_CH7,DMA_INT_TXC,ENABLE);DMA_ClearFlag(DMA1_FLAG_TC7,DMA1);DMA_ClrIntPendingBit(DMA1_INT_TXC7,DMA1);USART_EnableDMA(USART2,USART_DMAREQ_TX,ENABLE); }if( Port == UartPort3){//打开串口3的DMA发送 tx-DMA1-Channel2DMA_DeInit(DMA1_CH2);DMA_InitStructure.PeriphAddr = (INT32U)(&USART3->DAT);DMA_InitStructure.MemAddr = (INT32U)uart3_dma_tx;DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;DMA_InitStructure.BufSize = uart3_tx_len;DMA_InitStructure.PeriphInc = DMA_MEM_INC_DISABLE;DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;DMA_Init(DMA1_CH2, &DMA_InitStructure);DMA_EnableChannel(DMA1_CH2,DISABLE);NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = USART3_dma_Priority;NVIC_InitStructure.NVIC_IRQChannelSubPriority = USART3_dma_SubPriority;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);DMA_ConfigInt(DMA1_CH2,DMA_INT_TXC,ENABLE);DMA_ClearFlag(DMA1_FLAG_TC2,DMA1);DMA_ClrIntPendingBit(DMA1_INT_TXC2,DMA1);USART_EnableDMA(USART3,USART_DMAREQ_TX,ENABLE); }USART_Enable(UartDef[Port], ENABLE);
}
/*
*********************************************************************************************************
* 函 数 名: uart3_dma_tx_data
* 功能说明: 串口3DMA发送
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Mxg
* 创建时间: 20230214
*********************************************************************************************************
*/
void uart2_dma_tx_data(u8 *buff,u16 data_len){while(uart2_tx_flag);uart2_tx_flag = 1;DMA1_CH7->MADDR = (uint32_t)buff;DMA1_CH7->TXNUM = data_len;DMA_EnableChannel(DMA1_CH7,ENABLE);
}/*
*********************************************************************************************************
* 函 数 名: DMA1_Channel2_IRQHandler
* 功能说明: 串口3DMA发送完成中断
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Mxg
* 创建时间: 20230214
*********************************************************************************************************
*/
void DMA1_Channel7_IRQHandler(void){if(DMA_GetIntStatus(DMA1_INT_TXC7,DMA1)!=RESET){DMA_ClrIntPendingBit(DMA1_INT_TXC7,DMA1);USART_ClrFlag(USART2,USART_FLAG_TXC);DMA_EnableChannel(DMA1_CH7,DISABLE);uart2_tx_flag = 0;}
}/*
*********************************************************************************************************
* 函 数 名: uart3_dma_tx_data
* 功能说明: 串口3DMA发送
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Mxg
* 创建时间: 20230214
*********************************************************************************************************
*/
void uart3_dma_tx_data(u8 *buff,u16 data_len){while(uart3_tx_flag);uart3_tx_flag = 1;DMA1_CH2->MADDR = (uint32_t)buff;DMA1_CH2->TXNUM = data_len;DMA_EnableChannel(DMA1_CH2,ENABLE);
}/*
*********************************************************************************************************
* 函 数 名: DMA1_Channel2_IRQHandler
* 功能说明: 串口3DMA发送完成中断
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Mxg
* 创建时间: 20230214
*********************************************************************************************************
*/
void DMA1_Channel2_IRQHandler(void){if(DMA_GetIntStatus(DMA1_INT_TXC2,DMA1)!=RESET){DMA_ClrIntPendingBit(DMA1_INT_TXC2,DMA1);USART_ClrFlag(USART3,USART_FLAG_TXC);DMA_EnableChannel(DMA1_CH2,DISABLE);uart3_tx_flag = 0;}
}/*
*********************************************************************************************************
* 函 数 名: DrvUart_SendByte
* 功能说明: 串口发送byte
* 形 参: 选择port,需要发送的byte
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void DrvUart_SendByte(UartPort Port,INT8U byte)
{USART_SendData(UartDef[Port], byte);while (USART_GetFlagStatus(UartDef[Port], USART_FLAG_TXDE) == RESET);
}
/*
*********************************************************************************************************
* 函 数 名: DrvUart_SendString
* 功能说明: 串口发送String
* 形 参: 选择port,需要发送的String,字符串长度
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void DrvUart_SendString(UartPort Port,INT8U *str,INT8U len)
{INT8U i = 0;for( i = 0; i < len ; i++){if(*str=='\r')DrvUart_SendByte(Port,0x0d);else if(*str=='\n')DrvUart_SendByte(Port,0x0a);else DrvUart_SendByte(Port,*str);str++;}
}/*
*********************************************************************************************************
* 函 数 名: USART1_IRQHandler
* 功能说明: 串口1中断
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void USART1_IRQHandler(void)
{if(USART_GetIntStatus(USART1, USART_INT_RXDNE) != RESET){ }
}
/*
*********************************************************************************************************
* 函 数 名: USART2_IRQHandler
* 功能说明: 串口2中断
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void USART2_IRQHandler(void)
{if(USART_GetIntStatus(USART2, USART_INT_RXDNE) != RESET){USART_ClrIntPendingBit(USART2, USART_INT_RXDNE);}else if(USART_GetFlagStatus(USART2, USART_FLAG_IDLEF) != RESET){USART_ClrFlag(USART2, USART_FLAG_IDLEF);USART2->DAT;}
}
/*
*********************************************************************************************************
* 函 数 名: USART3_IRQHandler
* 功能说明: 串口3中断
* 形 参: 无
* 返 回 值: 无
* 创 建 人: Phyllis
* 创建时间: 20220219
*********************************************************************************************************
*/
void USART3_IRQHandler(void)
{if(USART_GetIntStatus(USART3, USART_INT_RXDNE) != RESET){USART_ClrIntPendingBit(USART3, USART_INT_RXDNE);
// DevRangModule_SetArray(1,USART_ReceiveData(USART3));}else if(USART_GetFlagStatus(USART3, USART_FLAG_IDLEF) != RESET){USART_ClrFlag(USART3, USART_FLAG_IDLEF);USART3->DAT;
// DevRangModule_ProcessData(1);}
}
.串口初始化
DrvUart_Init(UartPort2,USART2_Bound); DrvUart_Init(UartPort3,USART3_Bound);
串口号、波特率、优先级都在.h文件中更改。
dma发送调用函数:
uart3_dma_tx_data(test_buf,test_buf_len);
补充一下,串口初始化那没有开启时钟,我的时钟声明一般放在main函数里面统一声明的 ,如果没有在main函数里面声明,需要在结构体声明后面补一下:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);RCC_ConfigPclk1(RCC_HCLK_DIV4);RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM2, ENABLE); RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM3, ENABLE); RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4, ENABLE); RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM5, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA, ENABLE);RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB, ENABLE);RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1, ENABLE);RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART2, ENABLE);RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_USART3, ENABLE);RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN1, ENABLE);RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC2, ENABLE);