江科大DMA学习笔记

DMA(Direct Memory Access)直接存储器存储

DMA可以提供外设和存储器或存储器和存储器之间的高速数据传输,无需CPU干预,节省了CPU的资源(外设:数据寄存器等  存储器:Flash、Ram等)

c8t6DMA资源:DMA1(7个通道)

存储器映像
DMA框图

        试着理解上图:当我们想要进行DMA转运数据时,我们先要对DMA寄存器(AHB)进行配置。程序写在RAM里,因此CPU先从Flash里读取程序,然后通过系统进入总线矩阵,再进入AHB从设备对DMA寄存器进行配置。因此,DMA配置完成,数据可以凭借DMA进行转运。

DMA编程基本结构

        配置DMA时,需要外设和存储器的三个参数:起始地址、数据宽度、地址是否自增。

        传输寄存器的作用是转运次数,自动重装器的作用是当传输寄存器位0时,对传输寄存器进行重装。

        M2M(Memory to Memory)控制DMA触发是软件触发还是硬件触发。这里应注意软件触发时自动重装值为0,因为软件触发的目的是立刻完成DMA的转运从而完成接下来的任务,不应接着传输。

        写传输寄存器时,必须要先关闭DMA,再进行。不能在DMA开启时写传输寄存器,这是手册里的规定。

DMA请求映像

        EN使能端,EN为1时DMA工作,EN为0时DMA不工作。

        软件触发为可以理解为编程基本结构图里面的M2M位,为0时硬件触发,为1时软件触发。

        这里应注意的是,外设请求信号与DMA的通道是一一对应的,如ADC1的外设请求必须对应DMA的通道1,但是软件触发的话可随意指定通道。

代码解释
#include "stm32f10x.h"                  // Device header

uint16_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{
	MyDMA_Size = Size;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;//外设站点的基地址,32位
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//数据宽度
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//地址是否自增
	DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;//存储器站点的基地址
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//数据宽度
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//地址是否自增
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设站点是源端还是目的地
	DMA_InitStructure.DMA_BufferSize = Size;//传输寄存器,传输多少次
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//是否自动重装
	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;//是否软件触发
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//优先级
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, DISABLE);
}

void MyDMA_Transfer(void)
{
	DMA_Cmd(DMA1_Channel1, DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);//设置传输次数
	DMA_Cmd(DMA1_Channel1, ENABLE);
	
	while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//转运完成标志位
	DMA_ClearFlag(DMA1_FLAG_TC1);//清除标志位
}

        上面为软件触发DMA,MyDMA_Transfer(void)函数的作用为每次手动设置传输次数。防止软件触发开启循环模式使得DMA一直循环下去。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值