国民芯片G32N452 串口DMA发送代码

.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);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值