HC32 华大DMA 传输

1,DMA原理图

 2,功能描述 

1 使能 DMA 控制器
使用 DMA 时需要先将功能时钟控制 0 寄存器 FCG0.DMAx 位写 0 允许 DMA 的时钟
供给,再将 DMA 使能寄存器 DMA_EN.EN 位写 1。 同时, DMA 需要外围电路来启动
传输,所以 FCG0.PTDIS 外设电路触发功能位也需写 0。
当不使用 DMA,或者芯片需要进入 STOP 模式时,请将 DMA_EN.EN 设定为 0,并写
FCG0 关闭 DMA 时钟。 EN 写 0 前请先确认寄存器 DMA_CHSTAT.DMAACT 为 0,确
保 DMA 已完成所有传输。
2 通道选择和通道优先级
每个 DMA 控制单元中包含 8 个通道, 每个通道可以独立配置传输功能。
8 个通道优先级顺序为:通道 0>通道 1>通道 2>...>通道 7。
当一个 DMA 单元有多个通道请求传输时将按照优先级顺序执行。 但已处于传输中的
通道不会被打断,高优先通道需等当前通道传输完成后才会启动。
3 启动 DMA
DMA 通 过 外 围 电 路 产 生 的 请 求 启 动 , 这 些 请 求 通 过 触 发 源 选 择 寄 存 器
DMA_TRGSELx(x=0~7)进行配置,可以配置通道 x 的启动请求源。当外围电路产生启
动请求或软件写寄存器产生启动请求时, 并且 DMA 传输使能有效 DMA_EN.EN=1,
传输通道处于许可状态 DMA_CHEN.CHEN[x]=1,则启动通道 x 传输。
使用前,需要先将功能时钟控制 0 寄存器(FCG0)的外设电路触发功能及 DMA 功能使
能位置为有效。
4 数据块
DMA 每 次 启 动 传 输 的 数 据 量 用 块 (block) 表 示 , 块 的 大 小 由 数 据 控 制 寄 存 器
DMA_DTCTLx.BLKSIZE 设定, 最大可以设置 1024 个数据。 每个的数据宽度由
DMA_CHCTLx.HIZE 决定。
5 传输地址控制
传输的源地址和目标地址可以由寄存器设定为固定、递增、递减、 重载或者不连续跳
转。
固定: 源地址、 目标地址将在传输过程中固定不变。
递增及递减: 源地址、 目标地址将在每传输完成 1 个数据后根据 HSIZE 的值向前或向
后跳转。例如当 HSIZE 为 8bit 时,地址将每次增加/减少 1, 为 16bit 时每次增加/减少
2, 为 32bit 时每次增加/减少 4。
重载: 传输指定数量的数据后, 源、 目标地址将重新返回至最初的地址设定值。 地址
重载前需要传输的数据量,即重复区域的大小由寄存器 DMA_RPT 设定。
不连续地址传输: 传输指定数量的数据后, 源、 目标地址将跳过指定偏移量。地址跳
转的偏移量,以及跳转前需要传输的数据量,即不连续 区域的大小,由寄存器
DMA_SNSEQCTL/DMA_DNSEQCTL 设定。 当地址重载与不连续跳转的条件同时满足
时,执行地址重载。
6 传输次数
DMA 传输的总数据块的个数由数据控制寄存器 DMA_DTCTLx 的 CNT 位设定。传输
次数最多可设置 65535 次。 每传输一个数据块寄存器值减 1, 当寄存器值减为 0 时代
表本通道全部数据传输完成, 自动清除通道传输许可位 DMA_CHEN.CHEN[x],并产
生传输完成中断。 如果传输开始时 DMA_DTCTLx.CNT 被设为 0,表示无限次传输,
每次启动请求传输一个数据块, 但不清除通道传输许可位,也不会产生传输完成中断。
7 中断和事件信号输出
DMA 控制器可以产生以下 3 种中断:
数据块完成中断 DMA_BTCx: 完成一个数据块传输后产生。
传输完成中断 DMA_TCx: 完成寄存器 DMA_DTCTLx.CNT 设置的传输次数后产生。
传输错误中断 DMA_ERR: 当启动请求溢出(即通道的上一次请求还未响应时此通道
再次触发启动请求)时,或者, 传输过程中总线发生错误时产生此中断。其中,总线
错误时会同时终止传输并将该通道传输许可位 DMA_CHEN.CHEN[x]清零。
以上中断除了启动请求溢出错误外,其他中断都可以通过寄存器 DMA_CHCTLx.IE 设
置中断的有效或无效。 另外所有中断还配有独立的 MASK 寄存器,对中断进行屏蔽。
上述的 DMA_BTCx, DMA_TCx 中断同时也可以作为事件信号输出,可用作其它外围
电路的触发源,事件输出受 MASK 寄存器控制,但不受中断许可位 DMA_CHCTLx.IE
控制。 DMA_BTCx, DMA_TCx, DMA_ERR 事件发生会将对应的状态位寄存器置位,
不受 DMA_CHCTLx.IE、或 MASK 寄存器影响。

3,寄存器说明:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 寄存器介绍
1) DMA_EN: DMA 使能寄存器,使能或关闭 DMA 模块。
2) DMA_CHEN:通道使能寄存器,使能或关闭 DMA 通道, bit0~3 分别对应一个通道。
3) DMA_INSTAT0~1:中断状态寄存器(传输请求溢出错误中断、传输错误中断、块传输完
成中断、传输完成中断)。
4) DMA_INTMASK0~1:中断屏蔽寄存器,配置各中断是否屏蔽。
5) DMA_INTCLR0~1:中断复位寄存器,清空中断状态标志位。
应用笔记 Page 5 of 13
6) DMA_RCFGCTL:通道重置寄存器,配置 DMA 重置后的相关参数,包括:剩余传输次数
计数方式、目标/源地址重置方式、通道选择、链式传输等。
7) DMA_CHSTAT: 通道状态观测寄存器。
8) DMA_TRGSEL0~3:触发源选择寄存器,配置各通道启动传输的触发源,配置前需打开
PWR_FCG0 寄存器的 AOS 位。
9) DMA_TRGSELRC:通道重置触发源选择寄存器,配置启动通道重置的触发源。
10) DMA_SAR0~3:源地址寄存器,配置传输源地址。
11) DMA_DAR0~3:目标地址寄存器,配置传输目标地址。
12) DMA_DTCTL0~3:数据控制寄存器,配置传输次数和数据块大小。
13) DMA_RPT0~3:重复区域大小寄存器,配置源地址和目标地址重复区域大小。
14) DMA_RPTBB0~3: 重复区域大小寄存器 B,配置源地址和目标地址重复区域大小。
15) DMA_SNSEQCTL0~3: 源设备不连续地址传输控制寄存器,配置源地址跳转的地址偏移和
源地址跳转的数据量
16) DMA_SNSEQCTLB0~3: 源设备不连续地址传输控制寄存器 B,配置源不连续区域地址间
距和源地址跳转的数据量
17) DMA_DNSEQCTL0~3: 目标设备不连续地址传输控制寄存器,配置目标地址跳转的地址偏
移量和数据量
18) DMA_DNSEQCTLB0~3: 目标设备不连续地址传输控制寄存器 B,配置目标不连续区域地
址间距和目标地址跳转数据量
19) DMA_LLP0~3: 链指针寄存器,配置链指针
20) DMA_CHxCTL(x=0~3):通道控制寄存器
21) DMA_MONSARx , DMA_MONDARx , DMA_MONDTCTLx , DMA_MONRPTx ,
DMA_MONSNSEQCTLx, DMA_MONDNSEQCTLx:通道监视寄存器, DMA 每完成一
次传输请求后更新.

4,该传输可以配置源地址、目标地址在增加/减少至寄存器配置的重复区域大小时重新返回至
最初的地址设定值。重复区域的大小由寄存器 DMA_RPT 和 DMA_CHxCTL.HSIZE 的设定
值决定。

#include "hc32_ddl.h"

#define DDL_ON                                      (1U)
#define DDL_OFF                                     (0U)

#define DDL_ICG_ENABLE                              (DDL_ON)
#define DDL_UTILITY_ENABLE                          (DDL_ON)
#define DDL_PRINT_ENABLE                            (DDL_OFF)

#define DDL_ADC_ENABLE                              (DDL_OFF)
#define DDL_AES_ENABLE                              (DDL_OFF)
#define DDL_CAN_ENABLE                              (DDL_OFF)
#define DDL_CLK_ENABLE                              (DDL_ON)
#define DDL_CMP_ENABLE                              (DDL_OFF)
#define DDL_CRC_ENABLE                              (DDL_OFF)
#define DDL_CTC_ENABLE                              (DDL_OFF)
#define DDL_DAC_ENABLE                              (DDL_OFF)
#define DDL_DCU_ENABLE                              (DDL_OFF)
#define DDL_DMA_ENABLE                              (DDL_ON)
#define DDL_DMC_ENABLE                              (DDL_OFF)
#define DDL_DVP_ENABLE                              (DDL_OFF)
#define DDL_EFM_ENABLE                              (DDL_ON)
#define DDL_EMB_ENABLE                              (DDL_OFF)
#define DDL_ETH_ENABLE                              (DDL_OFF)
#define DDL_EVENT_PORT_ENABLE                       (DDL_OFF)
#define DDL_FCM_ENABLE                              (DDL_OFF)
#define DDL_FMAC_ENABLE                             (DDL_OFF)
#define DDL_GPIO_ENABLE                             (DDL_ON)
#define DDL_HASH_ENABLE                             (DDL_OFF)
#define DDL_HRPWM_ENABLE                            (DDL_OFF)
#define DDL_I2C_ENABLE                              (DDL_ON)
#define DDL_I2S_ENABLE                              (DDL_OFF)
#define DDL_INTERRUPTS_ENABLE                       (DDL_ON)
#define DDL_KEYSCAN_ENABLE                          (DDL_ON)
#define DDL_MAU_ENABLE                              (DDL_OFF)
#define DDL_MPU_ENABLE                              (DDL_OFF)
#define DDL_NFC_ENABLE                              (DDL_OFF)
#define DDL_OTS_ENABLE                              (DDL_OFF)
#define DDL_PWC_ENABLE                              (DDL_ON)
#define DDL_QSPI_ENABLE                             (DDL_OFF)
#define DDL_RMU_ENABLE                              (DDL_OFF)
#define DDL_RTC_ENABLE                              (DDL_OFF)
#define DDL_SDIOC_ENABLE                            (DDL_OFF)
#define DDL_SMC_ENABLE                              (DDL_OFF)
#define DDL_SPI_ENABLE                              (DDL_OFF)
#define DDL_SRAM_ENABLE                             (DDL_ON)
#define DDL_SWDT_ENABLE                             (DDL_OFF)
#define DDL_TMR0_ENABLE                             (DDL_OFF)
#define DDL_TMR2_ENABLE                             (DDL_OFF)
#define DDL_TMR4_ENABLE                             (DDL_OFF)
#define DDL_TMR6_ENABLE                             (DDL_OFF)
#define DDL_TMRA_ENABLE                             (DDL_OFF)
#define DDL_TRNG_ENABLE                             (DDL_OFF)
#define DDL_USART_ENABLE                            (DDL_OFF)
#define DDL_USBFS_ENABLE                            (DDL_OFF)
#define DDL_USBHS_ENABLE                            (DDL_OFF)
#define DDL_WDT_ENABLE                              (DDL_OFF)

#define BSP_ON                                      (1U)
#define BSP_OFF                                     (0U)

#define DMA_UNIT        (M4_DMA2)
#define DMA_CH          (DMA_CH4)
#define DMA_MX_CH       (DMA_MX_CH0)
#define DMA_TC          (4UL)
#define DMA_BC          (5UL)
#define DMA_DW          (DMA_DATAWIDTH_32BIT)
#define DMA_INT_SRC     (INT_DMA2_TC4)
#define DMA_IRQn        (Int000_IRQn)

static en_flag_status_t m_u8DmaTcEnd = Reset;

static const uint32_t u32SrcBuf[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                                       11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
static uint32_t u32DestBuf[20] = {0};
static uint32_t u32ExpectDestBufData[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
                                          13, 14, 15, 16, 17, 18, 19, 20};

static void Peripheral_WE(void)
{
    GPIO_Unlock();
    PWC_FCG0_Unlock();
    PWC_Unlock(PWC_UNLOCK_CODE_0);
    SRAM_WTCR_Unlock();
    EFM_Unlock();
}

static void Peripheral_WP(void)
{
    GPIO_Lock();
    PWC_FCG0_Lock();
    PWC_Lock(PWC_UNLOCK_CODE_0);
    SRAM_WTCR_Lock();
    EFM_Lock();
}

static void DmaInit(void)
{
    stc_dma_init_t stcDmaInit;

    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH, EVT_AOS_STRG);

    (void)DMA_StructInit(&stcDmaInit);

    stcDmaInit.u32IntEn     = DMA_INT_ENABLE;
    stcDmaInit.u32BlockSize = DMA_BC;
    stcDmaInit.u32TransCnt  = DMA_TC;
    stcDmaInit.u32DataWidth = DMA_DW;
    stcDmaInit.u32DestAddr  = (uint32_t)(&u32DestBuf[0]);
    stcDmaInit.u32SrcAddr   = (uint32_t)(&u32SrcBuf[0]);
    stcDmaInit.u32SrcInc    = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestInc   = DMA_DEST_ADDR_INC;

    (void)DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);
}

static void DMA2_CH4_TransEnd_IrqCallback(void)
{
    m_u8DmaTcEnd = Set;
    DMA_ClearTransIntStatus(DMA_UNIT, DMA_TC_INT_CH4);
}

static void DmaIntInit(void)
{
    stc_irq_signin_config_t stcIrqSignConfig;

    stcIrqSignConfig.enIntSrc   = DMA_INT_SRC;
    stcIrqSignConfig.enIRQn     = DMA_IRQn;
    stcIrqSignConfig.pfnCallback= &DMA2_CH4_TransEnd_IrqCallback;

    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    DMA_ClearTransIntStatus(DMA_UNIT, DMA_TC_INT_CH4);

    NVIC_ClearPendingIRQ(DMA_IRQn);
    NVIC_SetPriority(DMA_IRQn,DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_EnableIRQ(DMA_IRQn);
}

int32_t main(void)
{
    Peripheral_WE();
    BSP_CLK_Init();
    BSP_IO_Init();
    BSP_LED_Init();
    PWC_Fcg0PeriphClockCmd((PWC_FCG0_DMA2 | PWC_FCG0_AOS), Enable);
    Peripheral_WP();
    DmaInit();
    DmaIntInit();

    DMA_Cmd(DMA_UNIT, Enable);

    DMA_ChannelCmd(DMA_UNIT, DMA_CH, Enable);

    AOS_SW_Trigger();

    while (Reset == m_u8DmaTcEnd)
    {
        AOS_SW_Trigger();
    }
    if (0 != memcmp(u32DestBuf, u32ExpectDestBufData, sizeof(u32DestBuf)))
    {
        BSP_LED_On(LED_RED);
    }
    else
    {
        BSP_LED_On(LED_BLUE);
    }

    for (;;)
    {
        ;
    }
}

 

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上花开缓缓归以

你的鼓励将是我创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值