#一、DMA简介
#二、STM32存储器映像
#三、DMA基本结构
#四、项目代码
一、DMA简介
- DMA(Direct Memory Access)直接存储器存储
- DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须CPU干预,节省CPU的资源
- 12个独立可配置的通道:DMA1(7个通道),DMA2(5个通道)
- 每个通道都支持软件触发和特定的硬件触发
- STM32F103C8T6 DMA资源:DMA1(7个通道)
二、STM32存储器映像
- FLASH在DMA中只能读取不能写入,即FLASH只能作为外设或者存储器的起点,或可通过配置FLASH接口控制器进行写入
- SRAM可以任意读写
三、DMA基本结构
- 1.数据的地址及传输方向
- uint32_t DMA_PeripheralBaseAddr; //外设地址
- uint32_t DMA_MemoryBaseAddr; //存储器地址->建立数组 ,采用数组地址
- uint32_t DMA_DIR //传输方向
- 2.数据的大小及其传输单位
- uint32_t DMA_BufferSize; //传输数目
- uint32_t DMA_PeripheralInc; //外设地址增量模式
- uint32_t DMA_MemoryInc; //存储器地址增量模式
- uint32_t DMA_PeripheralDataSize; //外设数据宽度
- uint32_t DMA_MemoryDataSize; //存储器数据宽度
- 3.传输模式、优先级及存储器到存储器的模式
- uint32_t DMA_Mode; //模式选择
- uint32_t DMA_Priority; //通道优先级
- uint32_t DMA_M2M; //存储器到存储器模式
1)外设地址的查询:
外设数据寄存器地址=外设寄存器基本地址加数据寄存器偏移地址
如:USART1串口的数据寄存器地址
USART1寄存器基地址
USART1数据寄存器偏移地址(数据手册查找)
USART1的数据寄存器地址=基地址+偏移地址
2)传输方向(DIR):
-
内存到内存
-
内存到外设
-
外设到外设
-
外设到内存
-
DMA_DIR_PeripheralDST -> 外设作为目标地址
-
DMA_DIR_PeripheralSRC -> 外设作为源
3)传输数目
- 传输数目主要是通过传输计数器来实现计数工作,在DMA失能(Cmd_Disable)的时候可以设定计数次数,即一次完成多少次传输
4)增量模式
- 增量即完成一次数据传输后自动将数据地址加一,便于传输下一个数据
- 外设数据寄存器不选择增量
- 存储器地址选择增量,不选择自增数据则在第一个位置被一直覆盖
5)数据宽度
-
DMA_PeripheralDataSize_Byte (8位)
-
DMA_PeripheralDataSize_HalfWord (16位)
-
DMA_PeripheralDataSize_Word (32位)
-
根据外设数据寄存器和存储器选择大小
-
一般有外设数据寄存器的选择8位Byte
-
存储器与存储器之间传输则选择32位Word
6)模式选择
- DMA_Mode_Circular ->循环模式
- 当传输结束时,硬件自动将传输计数器重装,继续进行下一轮的传输
- DMA_Mode_Normal ->单次模式
- 当DMA完成一次传输后,DMA停止传送,即发送一次数据
7)通道选择
8)通道优先级
软件:每个通道的优先级可以在DMA_CCRx寄存器中设置,有四个等级:
- 最高优先级
- 高优先级
- 中等优先级
- 低优先级
硬件:如果2个请求有相同的软件优先级,则低编号的通道比较高编号的通道有较高的优先级,如:软件优先级相同,通道2优先于通道3
在大容量产品和互联型产品集中,DMA1控制器拥有高于DMA2控制器优先级
9)存储器到存储器模式
- 存储器到存储器传输则需要使能
- 其他情况失能即可
四、项目代码
DMA.C
#include "stm32f10x.h"
#include "DMA.h"
//const 关键字把数组Buffer定义为常量类型,表示数据存储在内部的Flash中
const uint32_t SRC_Buffer[BUFFER_SIZE]={
0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40
};
//定义DMA传输的目标存储器,存储在内部SRAM
uint32_t DST_Buffer[BUFFER_SIZE];
uint8_t SendBuf[SEND_SIZE];
/*
typedef struct
{
//1.数据的输入与输出
uint32_t DMA_PeripheralBaseAddr; //外设地址
uint32_t DMA_MemoryBaseAddr; //存储器地址
uint32_t DMA_DIR //传输方向
//2.数据大小及其传输单位
uint32_t DMA_BufferSize; //传输数目
uint32_t DMA_PeripheralInc; //外设地址增量模式
uint32_t DMA_MemoryInc; //存储器地址增量模式
uint32_t DMA_PeripheralDataSize; //外设数据宽度
uint32_t DMA_MemoryDataSize; //存储器数据宽度
//3.传输结束
uint32_t DMA_Mode; //模式选择
uint32_t DMA_Priority; //通道优先级
uint32_t DMA_M2M;