HC32F460_DMA

简介

HC32F460用户手册中的简介如下
注意:

  • 每一个DMA控制单元有4个通道
  • 单个数据块最大1024个数据,每个数据的宽度可选8、16、32位。也就是说单个数据块的数据容量最大为4KB。
  • 一次触发传输一个数据块,之后地址按照配置自增、重载、倒退或者跳转。
  • 每一次传输都会使得计数值减1,当减到0的时候DMA失效,需要重新使能。
  • 每一次触发传输一个数据块,引起一次块传输中断。计数值减为0的时候引起一次块传输中断和一次传输完成中断。
  • 可以设置重复区域限制Repeat Size,当DMA自增访问到重复区域限制的时候自动重载目的地址。
    在这里插入图片描述

DMA数据访问范围

所有外设和RAM均可达
在这里插入图片描述

示例,寄存器到数组

初步实现

内存中模拟一个寄存器和数组,将寄存器中的数据复制到数组中,每次DMA传输一个字节,一共传输4个字节


#define TEST_DMA_UNIT                 (M4_DMA1)
#define TEST_DMA_CLOCK_UNIT           (PWC_FCG0_PERIPH_DMA1)
#define TEST_DMA_CHANNEL              (DmaCh0)
#define TEST_DMA_TRIG_SOURCE          (EVT_AOS_STRG)

uint8_t __attribute__((aligned(4))) SImulate_REG_SRC = 0xB0;
uint8_t  __attribute__((aligned(4))) SImulate_DST_BUF[100] = {0};

static void BSP_DMA_Init(void)
{
	stc_dma_config_t stcDmaCfg;
	MEM_ZERO_STRUCT(stcDmaCfg);
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS, Enable);
	PWC_Fcg0PeriphClockCmd(TEST_DMA_CLOCK_UNIT, Enable);

    stcDmaCfg.u16BlockSize = 1u;		//1个数据块里有1个数据
    stcDmaCfg.u16TransferCnt = 4u;		//最多传输4个数据块
    stcDmaCfg.u32SrcAddr = (uint32_t)(&SImulate_REG_SRC);	//源地址
    stcDmaCfg.u32DesAddr = (uint32_t)(&SImulate_DST_BUF);	//目的地址
    stcDmaCfg.stcDmaChCfg.enSrcInc = AddressFix;		//源地址不变
    stcDmaCfg.stcDmaChCfg.enDesInc = AddressIncrease;	//目的地址自增
    stcDmaCfg.stcDmaChCfg.enTrnWidth = Dma8Bit;	//一个数据的宽度为8位
    stcDmaCfg.stcDmaChCfg.enIntEn = Disable;	//不使用中断
    stcDmaCfg.stcDmaChCfg.enDesRptEn = Disable; //不使用重复区域限制
    DMA_InitChannel(TEST_DMA_UNIT, TEST_DMA_CHANNEL, &stcDmaCfg);	
	DMA_SetTriggerSrc(TEST_DMA_UNIT, TEST_DMA_CHANNEL, TEST_DMA_TRIG_SOURCE);	//设置触发源为AOS中的软件触发
	DMA_Cmd(TEST_DMA_UNIT, Enable);
	DMA_ChannelCmd(TEST_DMA_UNIT, TEST_DMA_CHANNEL, Enable);
}

void entry_task1(void *pvParameters)
{
	while(1)
	{
		SImulate_REG_SRC++;		//源数据变化一次
		AOS_SW_Trigger();		//触发一次
		vTaskDelay(500);
	}
}

再上面的while1里打断点,手动控制逐次trigger,可以观察到现象如下

trigger -> {0xB1, 0x00, 0x00, 0x00, 0x00}
trigger -> {0xB1, 0xB2, 0x00, 0x00, 0x00}
trigger -> {0xB1, 0xB2, 0xB3, 0x00, 0x00}
trigger -> {0xB1, 0xB2, 0xB3, 0xB4, 0x00}
trigger -> {0xB1, 0xB2, 0xB3, 0xB4, 0x00}	//计数清0,trigger不再生效

绑定中断

增加中断相关宏定义和回调函数如下

/* DMA block transfer complete interrupt */
#define DMA_BTC_INT_NUM                 (INT_DMA1_BTC0)
#define DMA_BTC_INT_IRQn                (Int004_IRQn)
#define DMA_TC_INT_NUM                  (INT_DMA1_TC0)
#define DMA_TC_INT_IRQn                 (Int005_IRQn)

static void DmaBtcIrqCallback(void);
static void DmaTcIrqCallback(void);

static void DmaBtcIrqCallback(void)
{//块传输中断
	DMA_ClearIrqFlag(TEST_DMA_UNIT, TEST_DMA_CHANNEL, BlkTrnCpltIrq);
}
static void DmaTcIrqCallback(void)
{//传输完成中断
	DMA_ClearIrqFlag(TEST_DMA_UNIT, TEST_DMA_CHANNEL, TrnCpltIrq);
}

DMA初始化代码修改为使用中断

stcDmaCfg.stcDmaChCfg.enIntEn = Enable;	//使用中断

DMA初始化末尾增加如下代码

	stc_irq_regi_conf_t stcIrqRegiCfg;
    /* Set DMA block transfer complete IRQ */
    stcIrqRegiCfg.enIRQn = DMA_BTC_INT_IRQn;		//块传输中断
    stcIrqRegiCfg.pfnCallback = &DmaBtcIrqCallback;
    stcIrqRegiCfg.enIntSrc = DMA_BTC_INT_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);
	
	/* Set DMA transfer complete IRQ */
    stcIrqRegiCfg.enIRQn = DMA_TC_INT_IRQn;			//传输完成中断
    stcIrqRegiCfg.pfnCallback = &DmaTcIrqCallback;
    stcIrqRegiCfg.enIntSrc = DMA_TC_INT_NUM;
    enIrqRegistration(&stcIrqRegiCfg);
	NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
    NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
    NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);	

再while(1)中打断点,再块传输中断和传输完成中断打断点,现象如下

trigger -> {0xB1, 0x00, 0x00, 0x00, 0x00} ,块传输中断BTC
trigger -> {0xB1, 0xB2, 0x00, 0x00, 0x00},块传输中断BTC
trigger -> {0xB1, 0xB2, 0xB3, 0x00, 0x00},块传输中断BTC
trigger -> {0xB1, 0xB2, 0xB3, 0xB4, 0x00},块传输中断BTC,传输完成中断TC
trigger -> {0xB1, 0xB2, 0xB3, 0xB4, 0x00}	//计数清0,trigger不再生效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

菠萝地亚狂想曲

送我一瓶农夫山泉?

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

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

打赏作者

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

抵扣说明:

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

余额充值