GD32F307DMA实现串口收发

流程

选择端口,了解端口配置特性

DMA请求映射表

GPIO初始化和USARTx初始化

DMA初始化

DMA接收

DAM发送

中断服务函数

GD32F307串口端口定义

 DMA请求映射表

DMA0通道请求表
PeripheralCh0Ch1Ch2Ch3Ch4Ch5Ch6
USART/USART2_TXUSART2_RX

USART0_TX

USART0_RXUSART1_RXUSART1_TX

串口初始化

TX - 配置为复用推挽输出

RX - 配置为浮空输入

void UART1_Init(void)
{
	//使能中断,配置中断优先级
	nvic_irq_enable(USART1_IRQn, 0, 2);//中断源   抢占优先级,  响应优先级
	//配置GPIO
	rcu_periph_clock_enable(RCU_GPIOA);
	//使能UARTx时钟
	rcu_periph_clock_enable(RCU_USART1);
	//UART1 TX(PA2) Init
	gpio_init(UART1_TX_PORT,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,UART1_TX_PIN);
	//UART1 RX(PA3) Init
	gpio_init(UART1_RX_PORT,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,UART1_RX_PIN);

	//Reset UARTx
	usart_deinit(USART1);
	usart_baudrate_set(USART1,115200);//配置波特率
	usart_parity_config(USART1,USART_PM_NONE);//配置校验
	usart_word_length_set(USART1,USART_WL_8BIT);//配置数据长度
	usart_stop_bit_set(USART1,USART_STB_1BIT);//配置停止位
	usart_hardware_flow_rts_config(USART1,USART_RTS_DISABLE);//RTS Disable
	usart_hardware_flow_cts_config(USART1,USART_CTS_DISABLE);//CTS Disable
	usart_receive_config(USART1,USART_RECEIVE_ENABLE);//使能串口接收功能
	usart_transmit_config(USART1,USART_TRANSMIT_ENABLE);//使能串口发送功能
	usart_enable(USART1);//使能串口
	
	usart_interrupt_enable(USART1, USART_INT_IDLE);//使能RX空闲中断

}	

DMA初始化

DMA接收

void UART1_RevDMAConfig(void)
{
	dma_parameter_struct dma_struct;
	rcu_periph_clock_enable(RCU_DMA0);//使能时钟
	dma_deinit(DMA0,DMA_CH5);
	dma_struct_para_init(&dma_struct);
	dma_struct.direction = DMA_PERIPHERAL_TO_MEMORY;//传输方向 外设到内存
	dma_struct.memory_addr = (uint32_t)(uart1data_t.uc_dmarevbuf);//源地址
	dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
	dma_struct.number = DMA_BUFMAXSIZE;
	dma_struct.periph_addr = (uint32_t)USART1+4;//USART1+4
	dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
	dma_struct.priority = DMA_PRIORITY_HIGH;

	dma_init(DMA0,DMA_CH5,&dma_struct);
	
	dma_circulation_disable(DMA0, DMA_CH5);
	dma_memory_to_memory_disable(DMA0, DMA_CH5);
	dma_circulation_enable(DMA0, DMA_CH5);//启用循环接收数据
	//使能传输
	usart_dma_receive_config(USART1,USART_DENR_ENABLE);
	dma_channel_enable(DMA0, DMA_CH5);
}

DMA发送

void UART1_SendDMAConfig(unsigned char *buf,unsigned short int len)
{
	dma_parameter_struct dma_struct;
	rcu_periph_clock_enable(RCU_DMA0);//使能时钟
	dma_deinit(DMA0,DMA_CH6);
	dma_struct_para_init(&dma_struct);
	dma_struct.direction = DMA_MEMORY_TO_PERIPHERAL;//传输方向 内存到外设
	dma_struct.memory_addr = (uint32_t)(buf);//源地址
	dma_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
	dma_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
	dma_struct.number = len;
	dma_struct.periph_addr = (uint32_t)USART1+4;//USART1+4
	dma_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
	dma_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
	dma_struct.priority = DMA_PRIORITY_HIGH;

	dma_init(DMA0,DMA_CH6,&dma_struct);
	
	dma_circulation_disable(DMA0, DMA_CH6);
	dma_memory_to_memory_disable(DMA0, DMA_CH6);
	dma_circulation_disable(DMA0, DMA_CH6);//禁用循环接收数据
	//使能传输
	usart_dma_transmit_config(USART1,USART_DENT_ENABLE);
	dma_channel_enable(DMA0, DMA_CH6);
}

中断服务函数

void USART1_IRQHandler(void)
{
	if(RESET != usart_interrupt_flag_get(USART1,USART_INT_FLAG_IDLE))
	{
		usart_data_receive(USART1);
		DMA_DATA_Trea(&uart1data_t);
	}
	//检测过载错误
	if(RESET!=usart_interrupt_flag_get(USART1,USART_INT_FLAG_ERR_ORERR))
	{
		usart_data_receive(USART1);
	}
}

获取本次通讯的数据并回传到串口助手

    uartdata->ui_Point_Hend = uartdata->ui_Poing_End;//获取本次接收数据头指针
	uartdata->ui_Poing_End = DMA_BUFMAXSIZE - 
                            dma_transfer_number_get(DMA0,DMA_CH5);//获取本次数据尾指针
	
	//将接收到的数据发送到串口助手
	if(uartdata->ui_Poing_End>uartdata->ui_Point_Hend)
	{
		uartdata->ui_dmarevlen = uartdata->ui_Poing_End 
								- uartdata->ui_Point_Hend;
		for(i=0;i<uartdata->ui_dmarevlen;i++)
		{
			uartdata->uc_dmasendbuf[i] = 
			uartdata->uc_dmarevbuf[uartdata->ui_Point_Hend+i];
		}
		
	}
	else
	{
		for(i=0;i<DMA_BUFMAXSIZE-uartdata->ui_Point_Hend;i++)
		{
			uartdata->uc_dmasendbuf[i] =
			 uartdata->uc_dmarevbuf[uartdata->ui_Point_Hend+i];
		}
		
		for(i=0;i<uartdata->ui_Poing_End;i++)
		{
			uartdata->uc_dmasendbuf[DMA_BUFMAXSIZE-uartdata->ui_Point_Hend+i]
			 = uartdata->uc_dmarevbuf[i];
		}
		uartdata->ui_dmarevlen = 
		 DMA_BUFMAXSIZE-uartdata->ui_Point_Hend+uartdata->ui_Poing_End;
	}
	UART1_SendDMAConfig(uartdata->uc_dmasendbuf,uartdata->ui_dmarevlen);

串口通讯助手测试结果

​​​​​​​

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值