.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 128
void 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-Channel7
DMA_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-Channel2
DMA_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);