GD32 DMA串口接收发送

  • GD32 DMA串口接收

简介:GD32其实跟STM32差不多,有些程序简直可以在两个单片机上直接运行,但用GD32的库函数貌似比STM32的库函数比较复杂(可能是因为刚接触所以很多都没了解到,不熟悉),最近用到了串口DMA发送,但看官方的DEMO又没写得很仔细,就上网搜索了一下并记录下来。由于只用到的串口的DMA发送,并没有用到接收,所以本文只有发送,接收以后有空再补上。

①先确认所用串口发送是属于哪个DMA和哪一个通道

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CCD37OQ5-1590115506276)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20200522103208294.png)]
在这里插入图片描述

在这个工程中,我用的是串口2,所以应该发送对应的是DMA0的CH1,这一步是十分重要的,要是设置错误就白做了。

②初始化相对应的串口

这部分就略过了,串口初始化都差不多。

③初始化相对应的DMA通道

需要注意的是千万别忘了使能对应时钟!

其中USART2_DATA_ADDRESS指的是串口2存要发送数据的寄存器的地址,我用的单片机型号是GD32f103C8

#define USART2_DATA_ADDRESS      ((USART_BASE+(0x00000400U))+ (0x00000004U))
void uart2_dma_txinit(void)     
{     
		dma_parameter_struct dma_init_struct;
	
		/* enable DMA1 */
		rcu_periph_clock_enable(RCU_DMA0);
		dma_struct_para_init(&dma_init_struct);
		dma_deinit(DMA0, DMA_CH1);
		
		dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;//设置方向
        dma_init_struct.memory_addr = NULL;
        dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
        dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
        dma_init_struct.number = 0;
        dma_init_struct.periph_addr = USART2_DATA_ADDRESS;   //外设地址
        dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
        dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
        dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
        dma_init(DMA0, DMA_CH1, &dma_init_struct);
	
		/* configure DMA mode */
		dma_circulation_disable(DMA0, DMA_CH1);
		dma_memory_to_memory_disable(DMA0, DMA_CH1);
}

④编写DMA发送函数

void usart2_dma_send(uint8_t *buffer,uint16_t len)
{
	dma_channel_disable(DMA0, DMA_CH1);
	
	dma_memory_address_config(DMA0, DMA_CH1,(uint32_t)buffer);//设置要发送数据的内存地址
	dma_transfer_number_config(DMA0, DMA_CH1,len);//一共发多少个数据
	
	dma_channel_enable(DMA0, DMA_CH1);
	
  	usart_dma_transmit_config(UART_UART, USART_DENT_ENABLE);//使能串口DMA发送
	while(RESET == dma_flag_get(DMA0, DMA_CH1, DMA_FLAG_FTF));
}
	while(RESET == dma_flag_get(DMA0, DMA_CH1, DMA_FLAG_FTF));
}
  • 8
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
您好,关于 GD32F103 的串口接收 DMA,可以参考以下步骤: 1. 首先,需要配置串口DMA 的相关寄存器,例如串口的波特率、数据位数、停止位数、校验位等,以及 DMA 的通道、数据传输方向、传输数据类型等。 2. 然后,开启串口DMA 的时钟,并使能 DMA 的中断和传输完成中断。 3. 在串口接收中断中,将接收到的数据存入缓冲区中,并设置 DMA 的传输数据长度和缓冲区地址,启动 DMA 传输。同时需要注意,每次接收到数据后都要判断是否达到了缓冲区的最大长度,避免数据溢出。 4. 在 DMA 传输完成中断中,将接收到的数据进行处理,例如解析数据、更新状态等。 下面是一个简单的示例代码,供参考: ```c #include "gd32f10x.h" #define BUFFER_SIZE 256 uint8_t buffer[BUFFER_SIZE]; uint16_t buffer_index = 0; void usart_config(void) { /* Enable USART clock */ rcu_periph_clock_enable(RCU_USART0); /* USART0 configuration */ usart_deinit(USART0); usart_baudrate_set(USART0, 115200U); usart_word_length_set(USART0, USART_WL_8BIT); usart_stop_bit_set(USART0, USART_STB_1BIT); usart_parity_config(USART0, USART_PM_NONE); usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_dma_receive_config(USART0, USART_DENR_ENABLE); /* Enable USART DMA requests */ usart_dma_request_enable(USART0, USART_DENR); /* Enable USART */ usart_enable(USART0); } void dma_config(void) { /* Enable DMA clock */ rcu_periph_clock_enable(RCU_DMA0); /* DMA0 channel4 configuration */ dma_deinit(DMA0, DMA_CH4); dma_periph_address_config(DMA0, DMA_CH4, (uint32_t)&USART_DATA(USART0)); dma_memory_address_config(DMA0, DMA_CH4, (uint32_t)buffer); dma_transfer_direction_config(DMA0, DMA_CH4, DMA_PERIPHERAL_TO_MEMORY); dma_transfer_size_config(DMA0, DMA_CH4, DMA_MEMORY_WIDTH_8BIT, DMA_PERIPHERAL_WIDTH_8BIT); dma_memory_increment_enable(DMA0, DMA_CH4); dma_circulation_enable(DMA0, DMA_CH4); dma_interrupt_enable(DMA0, DMA_CH4, DMA_INT_FTF); dma_channel_enable(DMA0, DMA_CH4); } void nvic_config(void) { /* Enable DMA0 channel4 interrupt */ nvic_irq_enable(DMA0_Channel4_IRQn, 0, 0); } void DMA0_Channel4_IRQHandler(void) { if(dma_interrupt_flag_get(DMA0, DMA_CH4, DMA_INT_FTF)) { dma_interrupt_flag_clear(DMA0, DMA_CH4, DMA_INT_FTF); /* Process received data */ buffer_index = (BUFFER_SIZE - dma_transfer_number_get(DMA0, DMA_CH4)) % BUFFER_SIZE; // ... /* Restart DMA transmission */ dma_transfer_number_config(DMA0, DMA_CH4, BUFFER_SIZE); dma_channel_enable(DMA0, DMA_CH4); } } int main(void) { /* Configure USART */ usart_config(); /* Configure DMA */ dma_config(); /* Configure NVIC */ nvic_config(); while(1); } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值