STM32 DMA直接存储器存取

DMA

DMA简介

  1. DMA(Direct Memory Access)直接存储器存取,直接访问STM32内部的存储器(包括运行内存SRAM,程序存储器、Flash和寄存器等等),拥有权限访问存储器。
  2. DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无需CPU干预,节约CPU的资源。其中外设指外设的数据存储器、ADC的数据寄存器、串口的数据寄存器等等。
  3. 12个独立可配置的通道:DMA1(7个通道)、DMA2(5个通道)。
  4. 每个通道都支持软件触发和特定的硬件触发,Flash中数据转运到SRAM中一般使用软件触发,如果是外设和存储器,一般是硬件触发。
  5. STM32F103 DMA资源:DMA1(7个通道)无DMA2。

存储器映像

  1. 计算机系统的5大组成部分:运算器、控制器、存储器、输入设备和输出设备,其中运算器和控制器一般会合在一起,叫做CPU,计算机的1核心关键部分是CPU和存储器。
  2. bootloader程序是芯片出厂家自动写入的,一般也不允许我们修改选项字节,主要是对Flash的读保护以及写保护,内核外设寄存器各人外设的配置参数(NVIC、Systick),内核外设和其他外设是不同厂家生产设计的,所以地址分开。
    在这里插入图片描述
  3. Flash存储代码、SRAM存储变量、选项字节有读写保护

DMA框图

1. **Dcode总线专门访问Flash**,系统总线是访问其他东西的 2. 寄存器是连接软件和硬件的桥梁,寄存器可当作存储器 3. **仲裁器**:每个通道都可以传送数据,DMA总线只有一条。一次只能使用一次DMA转运数据 4. DMA和CPU都要访问同一个目标,DMA就会暂停CPU的访问,以防止冲突。(总线仍保证CPU得到一半的总线带宽 5. DMA即是主动单元,又是AHB总线的被动单元,AHB从设备,用于配置DMA请求

DMA基本结构

在这里插入图片描述

  1. ADC使用扫描模式,用DMA进行数据转运。不能再DMA Enable时改传输计数器。
  2. 传输计数器是一个大于0,递减的计数器,转送n此,转运为0,之前递增的地址也会恢复到起始地址,而传输计数器是否恢复到原来的值,是看转运的模式来决定
  3. DMA以最快的速度将传输计数器清0,(与ADC、外部中断不一样),软件触发和循环模式不能同时使用。

DMA请求

DMA配置

数据宽度与对齐

总结:高位舍弃、空出来的补0

代码

  1. RCC开启DMA的时钟
  2. 直接调用DMA_Init,初始化这里的各个参数(存储器的起始地址、数据宽度、地址是否自增、方向、传输计算器、是否需要自动重装、选择触发源、通道优先级-仲裁器)
  3. DMA_Cmd开启DMA请求
    Notice:在对应的外设调用一下XXX_DMACmd,开启触发信号的输出
    DMA中断:DMA_ITConfig,再再NVIC里,配置相应的中断通道,然后写中断函数就行了
    在转运的过程中,如果转运完成,传输计数器清0
    先Disable DMA再写传输计数器,再Enable DMA
    Request: 1. 传输计数器大于0
    2. 触发源由触发信号
    3. DMA 使能
    4. 条件满足则DMA 转运,否则停止转运
void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t bufferSize)
{
	BufferSize = bufferSize;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_InitTypeDef DMA_InitTypeDefStructure;
	DMA_InitTypeDefStructure.DMA_BufferSize = BufferSize;			// 传输计数器的值
	DMA_InitTypeDefStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitTypeDefStructure.DMA_M2M = DMA_M2M_Enable;
	DMA_InitTypeDefStructure.DMA_MemoryBaseAddr = AddrB;
	DMA_InitTypeDefStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitTypeDefStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitTypeDefStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitTypeDefStructure.DMA_PeripheralBaseAddr = AddrA;
	DMA_InitTypeDefStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitTypeDefStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
	DMA_InitTypeDefStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1, &DMA_InitTypeDefStructure);
	
	DMA_Cmd(DMA1_Channel1, ENABLE);
}

void MyDMA_Transfer()
{
	DMA_Cmd(DMA1_Channel1, DISABLE);
	DMA_SetCurrDataCounter(DMA1_Channel1, BufferSize);
	DMA_Cmd(DMA1_Channel1, ENABLE);
	
	while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);
	DMA_ClearFlag(DMA1_FLAG_TC1);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

威威轮到我了

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

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

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

打赏作者

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

抵扣说明:

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

余额充值