RH850 DMA UART UART通信使用DMA进行数据传输

DMA通信基本原理

DMA(Driect Memory Access),直接寄存器访问,DMA控制器通过硬件总线的方式将数据从源地址拷贝到目的地址,通过DMA进行数据传输过程中,不需要占用CPU。通过DMA进行数据传输,避免数据传输占用CPU资源,从而影响CPU对于其他事件的响应/处理速度。

DMA通信框图

DMA基本特性

DMA通道:2个DMA单元各8个通道,共16个DMA通道

传输数据大小:支持8bit,16bit,32bit数据传输

最大传输次数:65535

通道优先级:(0-15),设置为0优先级最高,15则最低

通道请求:每个DMA通道有特定的硬件触发请求,所有通道都可配置软件触发

硬件触发:配置DMA通道数据传输为硬件中断触发的方式,当对应的硬件中断发生,则开始执行DMA传输,外设与存储器,存储器与外设之间的通信可采用此方式。

软件触发:配置完DMA通道后,通过软件逻辑触发的方式进行DMA数据传输。

UART DMA数据发送流程

1)失能DMA通道传输功能,DTE = 0;

2)配置源地址DSA,目的地址DDA;

3)配置传输次数;

4)配置通道硬件触发,选择对应UART TX的使能中断号。注意:配置UART数据发送时先通过软件发送一个字节数据到UART,然后硬件触发DMA传输接下来的数据

5)使能DMA通道传输,使能DMA中断功能

UART DMA数据接收

1)失能DMA通道传输功能,DTE = 0;

2)配置源地址DSA,目的地址DDA;

3)配置传输次数(可设置循环接收);

4)配置通道硬件触发,选择对应UART RX的使能中断号

5)使能DMA通道传输,使能DMA中断功能

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是GD32F103 UART2使用DMA模式进行收发的例子,供您参考: ```c #include "gd32f10x.h" #define USART2_DR_ADDRESS ((uint32_t)0x40004404) #define USART2_DMA_CHANNEL_RX DMA_CHANNEL5 #define USART2_DMA_CHANNEL_TX DMA_CHANNEL6 #define USART2_DMA_STREAM_RX DMA0_STREAM5 #define USART2_DMA_STREAM_TX DMA0_STREAM6 uint8_t rx_buffer[10]; uint8_t tx_buffer[] = "Hello World!"; void usart2_init(void) { /* 使能 USART2 时钟和 DMA0 时钟 */ rcu_periph_clock_enable(RCU_USART2); rcu_periph_clock_enable(RCU_DMA0); /* 配置 USART2 引脚 */ gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3); /* 配置 USART2 参数 */ usart_deinit(USART2); usart_baudrate_set(USART2, 115200U); usart_word_length_set(USART2, USART_WL_8BIT); usart_stop_bit_set(USART2, USART_STB_1BIT); usart_parity_config(USART2, USART_PM_NONE); usart_hardware_flow_rts_config(USART2, USART_RTS_DISABLE); usart_hardware_flow_cts_config(USART2, USART_CTS_DISABLE); usart_receive_config(USART2, USART_RECEIVE_ENABLE); usart_transmit_config(USART2, USART_TRANSMIT_ENABLE); /* 配置 DMA 接收 */ dma_deinit(USART2_DMA_STREAM_RX); dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY; dma_init_struct.memory_addr = (uint32_t)rx_buffer; dma_init_struct.memory_inc = DMA_MEMORY_INC_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = 10; dma_init_struct.periph_addr = USART2_DR_ADDRESS; dma_init_struct.periph_inc = DMA_PERIPH_INC_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init(USART2_DMA_STREAM_RX, &dma_init_struct); dma_circulation_disable(USART2_DMA_STREAM_RX); dma_memory_to_memory_disable(USART2_DMA_STREAM_RX); dma_interrupt_enable(USART2_DMA_STREAM_RX, DMA_INT_FTF); /* 配置 DMA 发送 */ dma_deinit(USART2_DMA_STREAM_TX); dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL; dma_init_struct.memory_addr = (uint32_t)tx_buffer; dma_init_struct.memory_inc = DMA_MEMORY_INC_ENABLE; dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT; dma_init_struct.number = 12; dma_init_struct.periph_addr = USART2_DR_ADDRESS; dma_init_struct.periph_inc = DMA_PERIPH_INC_DISABLE; dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT; dma_init_struct.priority = DMA_PRIORITY_HIGH; dma_init(USART2_DMA_STREAM_TX, &dma_init_struct); dma_circulation_disable(USART2_DMA_STREAM_TX); dma_memory_to_memory_disable(USART2_DMA_STREAM_TX); dma_interrupt_enable(USART2_DMA_STREAM_TX, DMA_INT_FTF); /* 使能 USART2 DMA 发送和接收 */ usart_dma_receive_config(USART2, USART_DENR_ENABLE); usart_dma_transmit_config(USART2, USART_DENT_ENABLE); /* 使能 DMA0 */ dma_channel_enable(DMA0, USART2_DMA_CHANNEL_RX); dma_channel_enable(DMA0, USART2_DMA_CHANNEL_TX); /* 使能 USART2 */ usart_enable(USART2); } int main(void) { usart2_init(); /* 等待 DMA 接收完成 */ while(!dma_interrupt_flag_get(USART2_DMA_STREAM_RX, DMA_INT_FLAG_FTF)); dma_interrupt_flag_clear(USART2_DMA_STREAM_RX, DMA_INT_FLAG_FTF); /* 等待 DMA 发送完成 */ while(!dma_interrupt_flag_get(USART2_DMA_STREAM_TX, DMA_INT_FLAG_FTF)); dma_interrupt_flag_clear(USART2_DMA_STREAM_TX, DMA_INT_FLAG_FTF); while(1); } ``` 以上代码演示了如何使用GD32F103的USART2模块和DMA进行收发。在初始化函数`usart2_init()`中,首先使能USART2和DMA0的时钟,并配置USART2引脚和参数。接着,配置DMA接收和发送的相关参数,使能USART2的DMA接收和发送,并使能DMA0。在主函数中,等待DMA接收和发送完成后进入死循环。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值