当前位置:首页 > > 硅农亚历山大
[导读]在之前的内容里,我们使用过UART、SPI、I2C等接口进行过数据传输,在处理通信数据时,几乎都是在主程序或中断服务程序中进行数据的转存,这样耗费了大量的CPU时间。幸运的是,微控制器的设计者也考虑到这个问题,设计出了DMA(DirectMemoryAccess,直接存储器访问)...

在之前的内容里,我们使用过UART、SPI、I2C等接口进行过数据传输,在处理通信数据时,几乎都是在主程序或中断服务程序中进行数据的转存,这样耗费了大量的CPU时间。幸运的是,微控制器的设计者也考虑到这个问题,设计出了DMA(Direct Memory Access,直接存储器访问)传输功能,使得数据可以从一个地址空间复制到另一个地址空间,而不经过CPU,从而让CPU专注在其他功能上。本期内容我们以UARTDMA传输为例,简单介绍DMA的应用方法。
系统环境

Windows 10-64bit
软件平台

NucleiStudio IDE 202102版或 PlatformIO IDECoolTer
硬件需求

RV-STAR开发板

TTL-USB串口转换





DMA(直接内存访问)原理



DMA,全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另外一个地址空间。传输动作的初始化由CPU完成,而传输动作本身由DMA控制器来实行。典型的例子就是移动一个外部内存的区块到芯片内部更快的内存区。DMA的方式并没有让处理器工作拖延,反而可以去处理其他的工作。DMA对于高效能嵌入式系统算法和网络传输是很重要的。

在实现DMA传输时,是由DMA控制器直接掌管总线,因此,存在着一个总线控制权转移问题。即DMA传输前,CPU要把总线控制权交给DMA控制器,而在结束DMA传输后,DMA控制器应立即把总线控制权再交回给CPU。一个完整的DMA传输过程必须经过DMA请求、DMA响应、DMA传输、DMA结束4个步骤。




GD32VF103的DMA控制器


GD32VF103的DMA控制器有12个通道(DMA0有7个通道,DMA1有5个通道)。每个通道都是专门用来处理一个或多个外设的存储器访问请求的。DMA控制器内部实现了一个仲裁器,用来仲裁多个DMA请求的优先级。

DMA控制器和RISC-V内核共享系统总线,当DMA和CPU访问同样的地址空间时,DMA访问可能会阻挡CPU访问系统总线几个总线周期。总线矩阵中实现了循环仲裁算法来分配DMA与CPU的访问权,它可以确保CPU得到至少一半的系统总线带宽。



主要特征如下:

  • 传输数据长度可编程配置,最大到65536

  • 12个通道,并且每个通道都可配置(DMA0有7个通道,DMA1有5个通道)

  • AHB和APB外设,片上闪存和SRAM都可以作为访问的源端和目的端

  • 每个通道连接固定的硬件DMA请求

  • 支持软件优先级(低、中、高、极高)和硬件优先级(通道号越低,优先级越高)

  • 存储器和外设的数据传输宽度可配置:字节,半字,字

  • 存储器和外设的数据传输支持固定寻址和增量式寻址

  • 支持循环传输模式

  • 支持外设到存储器,存储器到外设,存储器到存储器的数据传输

  • 每个通道有3种类型的事件标志和独立的中断

  • 支持中断的使能和清除




实验部分


原理部分已经介绍过,DMA的工作过程比较简单,开发起来也比较容易,用户只需要结合数据手册,明确微控制器DMA通道和外设间对应关系,明确DMA的源地址、目的地址、数据宽度等信息,在开发时对DMA控制器和外设进行相应的使能和配置即可。

由于RV-STAR的USB串口(UART4)不支持DMA功能,本次的实验使用UART3进行:首先使用串口的DMA发送功能,让数据不经CPU直接从内存(txbuffer)传输到串口的发送端,然后使用串口的DMA接收功能接收10个字节的数据,保存到rxbuffer中,最后在主循环中(使用CPU)将rxbuffer接收到的数据再通过串口发送出去。


#include "nuclei_sdk_hal.h"

uint8_t rxbuffer[10];
uint8_t txbuffer[] = "\nUART DMA receive and transmit example, please input 10 bytes:\n";
#define ARRAYNUM(arr_name) (uint32_t)(sizeof(arr_name) / sizeof(*(arr_name)))

void uart_init();
void uart_send(int ch);

int main()
{
    dma_parameter_struct dma_init_struct;
    /* enable DMA1 */
    rcu_periph_clock_enable(RCU_DMA1);
    /* initialize UART3 */
    uart_init();

    /* deinitialize DMA Channel4(UART3_TX) */
    dma_deinit(DMA1, DMA_CH4);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = (uint32_t)txbuffer;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = ARRAYNUM(txbuffer) - 1;
    dma_init_struct.periph_addr = (uint32_t)
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭