5.4 DMA 使用说明

本章说明 N32G033 标准外设库中 DMA 驱动的文件组成、12 个公开函数,以及 FLASH_RAM 1 个示例。DMA 的请求映射、传输方向与存储器到存储器模式请配合用户手册的“DMA”章节阅读,芯片已知问题以勘误手册为准。

5.4.1 相关文件

相对路径 作用
firmware/n32g033_std_periph_driver/inc/n32g033_dma.h 定义 DMA_InitType 结构体与传输方向、地址增量、数据位宽、优先级、请求映射等宏,并按一段连续声明 12 个公开函数
firmware/n32g033_std_periph_driver/src/n32g033_dma.c 实现上述 12 个函数:通道复位与初始化、使能与传输计数、中断与标志处理、请求重映射
projects/n32g033_EVAL/examples/DMA/ DMA 示例根目录,含 FLASH_RAM 1 个示例
projects/n32g033_EVAL/examples/DMA/FLASH_RAM/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32g033_EVAL/bsp/ 示例共用的板级支持文件:log.h 提供串口日志接口

5.4.2 API 参考

搜索 API共 12 个函数

以下 12 个公开函数按 n32g033_dma.h 的声明顺序分为 1 组;每个条目给出功能摘要与 n32g033_dma.c 中该函数正上方的注释原文。

复位、初始化与传输控制

DMA_DeInit、DMA_Init、DMA_StructInit、DMA_EnableChannel、DMA_ConfigInt、DMA_SetCurrDataCounter、DMA_GetCurrDataCounter、DMA_GetFlagStatus、DMA_ClearFlag、DMA_GetIntStatus、DMA_ClrIntPendingBit、DMA_RequestRemap

void DMA_DeInit(DMA_ChannelType* DMAChx)将 DMA 通道 x 的 CHCFG、TXNUM、PADDR、MADDR、INTCLR 寄存器复位为默认值。
源码注释
name    DMA_DeInit.
fun     Reset CHCFG, TXNUM, PADDR, MADDR, INTCLR registers of DMA Channel x
        to their default reset values.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
return  none
void DMA_Init(DMA_ChannelType* DMAChx, DMA_InitType* DMA_InitParam)按 DMA_InitParam 初始化 DMA 通道 x,包括外设/存储器地址、传输方向、地址增量、数据位宽、优先级等。
源码注释
name    DMA_Init.
fun     Initializes the DMA Channel x by the structure parameter
        DMA_InitParam of type DMA_InitType. Includes configuration
        peripheral/memory address, transmission direction, address
        increment mode, data bit width, priority, etc.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param   DMA_InitParam (The input parameters must be the following values):
          - PeriphAddr
            -0x00000000~0xFFFFFFFF
          - MemAddr
            -0x00000000~0xFFFFFFFF
          - Direction
            - DMA_DIR_PERIPH_DST
            - DMA_DIR_PERIPH_SRC
          - BufSize
            -0x0000~0xFFFF
          - PeriphInc
            - DMA_PERIPH_INC_ENABLE
            - DMA_PERIPH_INC_DISABLE
          - DMA_MemoryInc
            - DMA_MEM_INC_ENABLE
            - DMA_MEM_INC_DISABLE
          - PeriphDataSize
            - DMA_PERIPH_DATA_SIZE_BYTE
            - DMA_PERIPH_DATA_SIZE_HALFWORD
            - DMA_PERIPH_DATA_SIZE_WORD
          - MemDataSize
            - DMA_MemoryDataSize_Byte
            - DMA_MemoryDataSize_HalfWord
            - DMA_MemoryDataSize_Word
          - CircularMode
            - DMA_MODE_CIRCULAR
            - DMA_MODE_NORMAL
          - Priority
            - DMA_PRIORITY_VERY_HIGH
            - DMA_PRIORITY_HIGH
            - DMA_PRIORITY_MEDIUM
            - DMA_PRIORITY_LOW
          - Mem2Mem
            - DMA_M2M_ENABLE
            - DMA_M2M_DISABLE
return  none
void DMA_StructInit(DMA_InitType* DMA_InitParam)用默认值填充用于初始化 DMA 的 DMA_InitType 结构体,通常在初始化该结构体之前调用。
源码注释
name    DMA_StructInit.
fun     Initializes the structure parameter of type DMA_InitType used to
        initialize DMA. This function is usually called before initializing
        a parameter of type DMA_InitType.
param   DMA_InitParam :
          - Pointer to the DMA_InitType structure which will be initialized.
return  none
void DMA_EnableChannel(DMA_ChannelType* DMAChx, FunctionalState Cmd)使能 DMA 通道 x;DMA 初始化成功后调用该函数开始搬运数据。
源码注释
name    DMA_EnableChannel.
fun     DMA Channel x Channel enable. This function is called after DMA
        initialization is successful to start moving data.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param  Cmd:(The input parameters must be the following values)
            - ENABLE
            - DISABLE
return  none
void DMA_ConfigInt(DMA_ChannelType* DMAChx, uint32_t DMAInt, FunctionalState Cmd)使能 DMA 通道 x 的中断,包括传输完成、半传输与传输错误中断。
源码注释
name    DMA_ConfigInt.
fun     DMA Channel x interrupts enable. Before enabling a DMA channel,
        enabling transfer completion interrupt, half-transfer interrupt
        or transfer error interrupt will cause an interrupt when the
        corresponding event occurs.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param   DMAInt (The input parameters must be the following values):
          - DMA_INT_TXC
          - DMA_INT_HTX
          - DMA_INT_ERR
param  Cmd:(The input parameters must be the following values)
            - ENABLE
            - DISABLE
return  none
void DMA_SetCurrDataCounter(DMA_ChannelType* DMAChx, uint16_t DataNumber)设置 DMA 通道 x 本次要传输的数据个数。
源码注释
name    DMA_SetCurrDataCounter.
fun     Set the current number of data transfers for DMA Channel x.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param   DataNumber(The input parameters must be the following values) :
          - 0~0xFFFF
return  none
note    This function can only be used when the DMAChx is disabled.
uint16_t DMA_GetCurrDataCounter(const DMA_ChannelType* DMAChx)获取 DMA 通道 x 当前剩余待传输的数据个数。
源码注释
name    DMA_GetCurrDataCounter.
fun     Get the current number of remaining data for DMA Channel x.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
return  Returns the number of bytes remaining to be transferred.
FlagStatus DMA_GetFlagStatus(uint32_t DMAFlag, const DMA_Module* DMAy)获取 DMA 通道 x 的标志状态,包括全局标志、传输完成、半传输与传输错误标志。
源码注释
name    DMA_GetFlagStatus.
fun     Get DMA Channel x flag status. Contains the global flag, transfer
        completion flag, half-transfer flag, and transfer error flag for
        the corresponding channel.
param   DMAFlag (The input parameters must be the following values):
          - DMA_FLAG_GL1
          - DMA_FLAG_TC1
          - DMA_FLAG_HT1
          - DMA_FLAG_TE1
          - DMA_FLAG_GL2
          - DMA_FLAG_TC2
          - DMA_FLAG_HT2
          - DMA_FLAG_TE2
          - DMA_FLAG_GL3
          - DMA_FLAG_TC3
          - DMA_FLAG_HT3
          - DMA_FLAG_TE3
param   DMAy (The input parameters must be the following values):
          - DMA
return  SET or RESET.
void DMA_ClearFlag(uint32_t DMAFlag, DMA_Module* DMAy)清除 DMA 通道 x 的标志状态,包括全局标志、传输完成、半传输与传输错误标志。
源码注释
name    DMA_ClearFlag.
fun     Clear DMA Channel x flag status. Contains the global flag, transfer
        completion flag, half-transfer flag, and transfer error flag for the
        corresponding channel.
param   DMAFlag (The input parameters must be the following values):
          - DMA_FLAG_GL1
          - DMA_FLAG_TC1
          - DMA_FLAG_HT1
          - DMA_FLAG_TE1
          - DMA_FLAG_GL2
          - DMA_FLAG_TC2
          - DMA_FLAG_HT2
          - DMA_FLAG_TE2
          - DMA_FLAG_GL3
          - DMA_FLAG_TC3
          - DMA_FLAG_HT3
          - DMA_FLAG_TE3
param   DMAy (The input parameters must be the following values):
          - DMA
return  none.
INTStatus DMA_GetIntStatus(uint32_t DMA_IT, const DMA_Module* DMAy)获取 DMA 通道 x 的中断状态,包括全局中断、传输完成、半传输与传输错误中断。
源码注释
name    DMA_GetIntStatus.
fun     Get DMA Channel x interrupt status. Contains the global interrupt,
        transfer completion interrupt, half-transfer interrupt, and transfer
        error interrupt for the corresponding channel.
param   DMA_IT (The input parameters must be the following values):
          - DMA_INT_GLB1
          - DMA_INT_TXC1
          - DMA_INT_HTX1
          - DMA_INT_ERR1
          - DMA_INT_GLB2
          - DMA_INT_TXC2
          - DMA_INT_HTX2
          - DMA_INT_ERR2
          - DMA_INT_GLB3
          - DMA_INT_TXC3
          - DMA_INT_HTX3
          - DMA_INT_ERR3
param   DMAy (The input parameters must be the following values):
          - DMA
return  SET or RESET.
note    Global interrupt status is the logic or generation of transfer completion
        interrupt, half-transfer interrupt, transfer error interrupt.
void DMA_ClrIntPendingBit(uint32_t DMA_IT, DMA_Module* DMAy)清除 DMA 通道 x 的中断状态位,包括全局中断、传输完成、半传输与传输错误中断。
源码注释
name    DMA_ClrIntPendingBit.
fun     Clear DMA Channel x interrupt status bits. Contains the global interrupt,
        transfer completion interrupt, half-transfer interrupt, and transfer
        error interrupt for the corresponding channel.
param   DMA_IT (The input parameters must be the following values):
          - DMA_INT_GLB1
          - DMA_INT_TXC1
          - DMA_INT_HTX1
          - DMA_INT_ERR1
          - DMA_INT_GLB2
          - DMA_INT_TXC2
          - DMA_INT_HTX2
          - DMA_INT_ERR2
          - DMA_INT_GLB3
          - DMA_INT_TXC3
          - DMA_INT_HTX3
          - DMA_INT_ERR3
param   DMAy (The input parameters must be the following values):
          - DMA
return  none.
note    Global interrupt state is the logic or generation of transfer completion
        interrupt, half-transfer interrupt, transfer error interrupt. In fact,
        after clearing the three interrupt states, the global interrupt state
        will also be cleared.
void DMA_RequestRemap(uint32_t DMA_REMAP, const DMA_Module* DMAy, DMA_ChannelType* DMAChx, FunctionalState Cmd)设置 DMA 通道 x 的请求重映射,可把任意 DMA 请求映射到任意通道;同一时刻每个通道只能有一个 DMA 请求。
源码注释
name    DMA_RequestRemap.
fun     Set DMA Channel x's remap request. Channel request mapping is flexible,
        allowing users to map any DMA request to any DMA channel as needed. It
        is important to note that there can be only one DMA request per DMA
        channel at a time.
param   DMA_REMAP (The input parameters must be the following values):
          - DMA_REMAP_UART1_TX
          - DMA_REMAP_UART1_RX
          - DMA_REMAP_UART2_TX
          - DMA_REMAP_UART2_RX
          - DMA_REMAP_UART3_TX
          - DMA_REMAP_UART3_RX
          - DMA_REMAP_SPI1_TX
          - DMA_REMAP_SPI1_RX
          - DMA_REMAP_SPI2_TX
          - DMA_REMAP_SPI2_RX
          - DMA_REMAP_I2C1_TX
          - DMA_REMAP_I2C1_RX
          - DMA_REMAP_I2C2_TX
          - DMA_REMAP_I2C2_RX
          - DMA_REMAP_TIM1_CH1
          - DMA_REMAP_TIM1_CH2
          - DMA_REMAP_TIM1_CH3
          - DMA_REMAP_TIM1_CH4
          - DMA_REMAP_TIM1_COM
          - DMA_REMAP_TIM1_UP
          - DMA_REMAP_TIM1_TRIG
          - DMA_REMAP_TIM3_CH1
          - DMA_REMAP_TIM3_CH2
          - DMA_REMAP_TIM3_CH3
          - DMA_REMAP_TIM3_CH4
          - DMA_REMAP_TIM3_UP
          - DMA_REMAP_TIM3_TRIG
          - DMA_REMAP_TIM4_CH1
          - DMA_REMAP_TIM4_CH2
          - DMA_REMAP_TIM4_CH3
          - DMA_REMAP_TIM4_UP
          - DMA_REMAP_TIM4_TRIG
          - DMA_REMAP_TIM6_UP
          - DMA_REMAP_RESERVED
param   DMAy (The input parameters must be the following values):
          - DMA
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param  Cmd:(The input parameters must be the following values)
            - ENABLE
            - DISABLE
return  none.

5.4.3 Demo 示例说明

本节说明 DMA 的 1 个示例:FLASH_RAM 用存储器到存储器模式把 FLASH 中的常量数组搬到 RAM 并做校验。

5.4.3.1 FLASH_RAM 存储器到存储器传输

工程目录: projects/n32g033_EVAL/examples/DMA/FLASH_RAM/

使能 DMA 时钟并打开通道中断→配置通道的源地址、目标地址与传输长度→启动存储器到存储器传输→传输完成中断读取剩余计数并清标志→串口打印校验结果

项目 源码解读
功能 用 DMA 的存储器到存储器模式把 FLASH 中的常量数组 SRC_Const_Buffer 搬到 RAM 数组 DST_Buffer,搬运完成后用 memcmp 比较并在串口打印结果。
源码组成 src/main.c 含 main、RCC_Configuration 与 NVIC_Configuration;
src/n32g033_it.c 中的 DMA_IRQ_HANDLER 读取剩余计数并清中断标志;
inc/main.h、inc/n32g033_it.h 给出声明;
readme.txt 给出测试步骤;
工程文件在 MDK-ARM/ 与 EWARM/。
关键配置 通道:DMA_CH1;
源为 FLASH 常量数组 SRC_Const_Buffer,目标为 RAM 数组 DST_Buffer;
传输方向 DMA_DIR_PERIPH_SRC、存储器到存储器使能、字(Word)数据宽度;
源与目标地址均递增、普通模式、高优先级;
传输完成中断使能,请求源重映射到保留项。
程序与数据路径 main → RCC_Configuration 打开 AHB 上的 DMA 时钟 → NVIC_Configuration 使能 DMA 中断 → DMA_DeInit、DMA_StructInit、DMA_Init 配置通道 → DMA_RequestRemap 映射保留请求 → DMA_ConfigInt 使能传输完成中断 → DMA_EnableChannel 启动传输 → 等待剩余计数归零 → memcmp 校验后打印结果。
主要 API DMA_DeInit、DMA_StructInit、DMA_Init、DMA_RequestRemap、DMA_ConfigInt、DMA_GetCurrDataCounter、DMA_EnableChannel、DMA_GetIntStatus、DMA_ClrIntPendingBit
验证方法 硬件基于评估板 N32G033K8Q7-1_STB V1.0,串口 TX 为 PA9、RX 为 PA10,波特率 115200;
编译下载复位运行后,串口打印 DMA Flash to RAM passed 表示搬运与校验成功。
使用提示 系统时钟 64 MHz;
存储器到存储器模式不使用外设请求,示例把请求源重映射到保留项,否则请求会落到 UART1_TX 上。
核心代码解读与移植

示例用 DMA 的存储器到存储器模式在 FLASH 与 RAM 之间搬数,搬运结束后校验两侧内容是否一致。

数据路径: RCC_Configuration 打开 DMA 时钟 → NVIC_Configuration 使能 DMA 中断 → DMA_Init 配置源地址、目标地址与传输长度 → DMA_EnableChannel 启动传输 → 传输完成中断读取剩余计数并清标志 → memcmp 校验数据

1. 时钟与中断一起打开。 DMA 挂在 AHB 总线上,要先打开它的时钟,再把通道中断接入 NVIC,否则传输完成事件不会进入中断。

src/main.csrc/main.c · RCC_Configuration
void RCC_Configuration(void)
{
    /* Enable DMA clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
}
src/main.csrc/main.c · NVIC_Configuration
    NVIC_InitType NVIC_InitStructure;

    /* Enable DMA IRQ Channel */
    NVIC_InitStructure.NVIC_IRQChannel                   = DMA_IRQN;
    NVIC_InitStructure.NVIC_IRQChannelPriority           = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

换用其他 DMA 通道时同步修改中断号;DMA 的时钟位在 AHB 上而不是 APB,写错总线会让通道无法工作。

2. 地址与传输参数一次配好。 DMA_StructInit 给默认值后,用结构体指定源地址、目标地址、传输方向、数据宽度与存储器到存储器模式。

src/main.csrc/main.c · main
    DMA_DeInit(DMA_CHANNEL_USED);
    DMA_StructInit(&DMA_InitStructure);
    DMA_InitStructure.PeriphAddr     = (uint32_t)SRC_Const_Buffer;
    DMA_InitStructure.MemAddr        = (uint32_t)DST_Buffer;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = BUFFER_SIZE;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_ENABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_WORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_Word;
    DMA_InitStructure.CircularMode   = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_ENABLE;
    DMA_Init(DMA_CHANNEL_USED, &DMA_InitStructure);

Direction 取 DMA_DIR_PERIPH_SRC 表示把 PeriphAddr 当作数据源;存储器到存储器模式下两个地址都可以递增。

3. 启动前先重映射并读取初值。 存储器到存储器模式建议把请求源重映射到保留项,随后使能传输完成中断与读取起始计数,再使能通道。

src/main.csrc/main.c · main
    /* In memory-to-memory mode, it is recommended to set an reserved
    peripheral request source in the system, otherwise the request
    will be mapped to the UART1_TX. */
    DMA_RequestRemap(DMA_REMAP_RESERVED, DMA, DMA_CHANNEL_USED, ENABLE);

    /* Enable DMA Channel Transfer Complete interrupt */
    DMA_ConfigInt(DMA_CHANNEL_USED, DMA_INT_TXC, ENABLE);

    /* Get Current Data Counter value before transfer begins */
    CurrDataCounterBegin = DMA_GetCurrDataCounter(DMA_CHANNEL_USED);

    /* Enable DMA Channel transfer */
    DMA_EnableChannel(DMA_CHANNEL_USED, ENABLE);

    /* Wait the end of transmission */
    while (CurrDataCounterEnd != 0)
    {
    }

等待剩余计数归零的 while 循环是示例的同步方式;实际工程里用中断或标志位判断传输结束更稳妥。

4. 中断读回剩余计数并清标志,主流程做校验。 DMA_IRQ_HANDLER 在传输完成时读取剩余数据个数并清全局中断标志,主流程再用 memcmp 比较源与目标数组。

src/n32g033_it.csrc/n32g033_it.c · DMA_IRQ_HANDLER
void DMA_IRQ_HANDLER(void)
{
    /* Test on DMA channel Transfer Complete interrupt */
    if (DMA_GetIntStatus(DMA_IT_FLAG_TC, DMA))
    {
        /* Get Current Data Counter value after complete transfer */
        CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA_CHANNEL_USED);
        /* Clear DMA channel Half Transfer, Transfer Complete and Global interrupt pending bits */
        DMA_ClrIntPendingBit(DMA_IT_FLAG_GL, DMA);
    }
}
src/main.csrc/main.c · main
    if (memcmp(SRC_Const_Buffer, DST_Buffer, BUFFER_SIZE) == 0)
    {
        log_info("DMA Flash to RAM passed\n");
    }
    else
    {
        log_error("DMA Flash to RAM failed\n");
    }

DMA_IRQ_HANDLER 上方的注释沿用了 SysTick_Handler 的名字,与实际函数名不一致,阅读时以函数定义为准。

对应源码: src/main.c、src/n32g033_it.c、firmware/n32g033_std_periph_driver/inc/n32g033_dma.h

5.4.4 注意与排障

场景 检查与建议 来源
存储器到存储器模式 用户手册 DMA 章写明该模式不使用外设请求,需要重映射请求源;
按手册把请求源映射到保留项,避免请求落到 UART1_TX。
用户手册
传输数据个数 用户手册 DMA 章写明传输个数须在通道使能前设置,DMA_SetCurrDataCounter 只能在通道关闭时调用;
改传输长度前先关闭通道。
用户手册
中断与标志清除 用户手册 DMA 章写明全局中断状态是传输完成、半传输与传输错误三者的逻辑或;
清除三个中断状态后全局中断状态随之清除。
用户手册
外设时钟总线 用户手册 DMA 章写明 DMA 使用 AHB 时钟;
使能时钟时确认选择的是 AHB 外设位。
用户手册

勘误手册 V1.0.0(2025.9.25)针对 A 版芯片,未列出 DMA 相关条目。

国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计