一. DMA简介
-
DMA(Direct Memory Access,直接存储器访问) 传输将数据从一个地址空间复制到另外一个地址空间。而且不占用CPU
-
数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH。
-
我们把外设简称为: P, 把寄存器简称为: M
-
DMA 控制器包含了 DMA1 和 DMA2,其中 DMA1 有 7 个通道,DMA2 有 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存在于大容量的单片机中。
1. DMA功能框图
关键角色:
- DMA请求 : 发送方向MCU请求使用DMA通道发送数据
- 通道 : 传输数据的管道
具体通道分配方法:
但是通道表里并没有 存储器到存储器 (M →M的)请求映像, 因为: 它每个通道都可以用!!!!
- 仲裁器 :
当多个DMA请求一起来怎么办?
使用仲裁器来管理
①. 软件优先级 : DMA_CCRx : PL[1:0]寄存器配置其优先级 , 分为: 低, 中, 高, 最高
②. 硬件优先级 : DMA1>DMA2 , 通道号小的优先
二. DMA相关结构体
1. DMA_ InitTypeDef 初始化结构体
typedef struct
{
uint32_t DMA_PeripheralBaseAddr; // 外设地址
uint32_t DMA_MemoryBaseAddr; // 存储器地址
uint32_t DMA_DIR; // 传输方向
uint32_t DMA_BufferSize; // 传输数目
uint32_t DMA_PeripheralInc; // 外设地址增量模式
uint32_t DMA_MemoryInc; // 存储器地址增量模式
uint32_t DMA_PeripheralDataSize; // 外设数据宽度
uint32_t DMA_MemoryDataSize; // 存储器数据宽度
uint32_t DMA_Mode; // 模式选择
uint32_t DMA_Priority; // 通道优先级
uint32_t DMA_M2M; // 存储器到存储器模式
} DMA_InitTypeDef;
参数详解 :
(1). 数剧从哪来到哪去
- 外设地址 : 配置的是DMA_CPAR 寄存器, 一般设置为外设的数据寄存器地址,如果是存储器到存储器模式则设置为其中一个存储器地址。
- 存储器地址 : 设定DMA_CMAR 寄存器值;一般设置为我们自定义存储区的首地址。
- 传输方向 : 传输方向选择, 可选外设到存储器、存储器到外设。它设定DMA_CCR 寄存器的DIR[1:0]位的值。这里并没有存储器到存储器的方向选择,当使用存储器到存储器时,只需要把其中一个存储器当作外设使用即可。
(2). 数剧传多少, 传的单位是什么?
- 传输数目 : 设定待传输数据数目,初始化设定DMA_CNDTR 寄存器的值
- 外设地址增量模式 : 外设地址是否自动递增 (比如外设是个串口寄存器,那就不要递增, 如果是个存储单元则要递增)
- 存储器地址增量模式存储器地址是否自动递增,我们自定义的存储区一般都是存放多个数据的,所以要使能存储器地址自动递增功能
- 外设数据宽度 : 可选字节(8 位)、半字(16 位)和字(32位),它设定DMA_CCR 寄存器的PSIZE[1:0]位的值。
- 存储器数据宽度 : 可选字节(8 位)、半字(16 位)和字(32位),它设定DMA_CCR 寄存器的MSIZE[1:0]位的值。当外设和存储器之间传数据时,两边的数据宽度应该设置为一致大小。
(3). 什么时候传输结束?
- 模式选择 : DMA 传输模式选择, 可选一次传输或者循环传输
(4). 其他设置
- 通道优先级 : 设置通道优先级
- 存储器到存储器模式 : 当M2M时设置
三. DMA相关库函数
1. DMA初始化 DMA_Init
例如: DMA_Init(DMA1_Channel7, &DMA_InitStruct)
2. DMA使能 DMA_Cmd
3. DMA状态查询 FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
DMAy_FLAG可以传入以下值:
* This parameter can be one of the following values:
* @arg DMA1_FLAG_GL1: DMA1 Channel1 global flag.
* @arg DMA1_FLAG_TC1: DMA1 Channel1 transfer complete flag.
* @arg DMA1_FLAG_HT1: DMA1 Channel1 half transfer flag.
* @arg DMA1_FLAG_TE1: DMA1 Channel1 transfer error flag.
* @arg DMA1_FLAG_GL2: DMA1 Channel2 global flag.
* @arg DMA1_FLAG_TC2: DMA1 Channel2 transfer complete flag.
* @arg DMA1_FLAG_HT2: DMA1 Channel2 half transfer flag.
* @arg DMA1_FLAG_TE2: DMA1 Channel2 transfer error flag.
* @arg DMA1_FLAG_GL3: DMA1 Channel3 global flag.
* @arg DMA1_FLAG_TC3: DMA1 Channel3 transfer complete flag.
* @arg DMA1_FLAG_HT3: DMA1 Channel3 half transfer flag.
* @arg DMA1_FLAG_TE3: DMA1 Channel3 transfer error flag.
* @arg DMA1_FLAG_GL4: DMA1 Channel4 global flag.
* @arg DMA1_FLAG_TC4: DMA1 Channel4 transfer complete flag.
* @arg DMA1_FLAG_HT4: DMA1 Channel4 half transfer flag.
* @arg DMA1_FLAG_TE4: DMA1 Channel4 transfer error flag.
* @arg DMA1_FLAG_GL5: DMA1 Channel5 global flag.
* @arg DMA1_FLAG_TC5: DMA1 Channel5 transfer complete flag.
* @arg DMA1_FLAG_HT5: DMA1 Channel5 half transfer flag.
* @arg DMA1_FLAG_TE5: DMA1 Channel5 transfer error flag.
* @arg DMA1_FLAG_GL6: DMA1 Channel6 global flag.
* @arg DMA1_FLAG_TC6: DMA1 Channel6 transfer complete flag.
* @arg DMA1_FLAG_HT6: DMA1 Channel6 half transfer flag.
* @arg DMA1_FLAG_TE6: DMA1 Channel6 transfer error flag.
* @arg DMA1_FLAG_GL7: DMA1 Channel7 global flag.
* @arg DMA1_FLAG_TC7: DMA1 Channel7 transfer complete flag.
* @arg DMA1_FLAG_HT7: DMA1 Channel7 half transfer flag.
* @arg DMA1_FLAG_TE7: DMA1 Channel7 transfer error flag.
* @arg DMA2_FLAG_GL1: DMA2 Channel1 global flag.
* @arg DMA2_FLAG_TC1: DMA2 Channel1 transfer complete flag.
* @arg DMA2_FLAG_HT1: DMA2 Channel1 half transfer flag.
* @arg DMA2_FLAG_TE1: DMA2 Channel1 transfer error flag.
* @arg DMA2_FLAG_GL2: DMA2 Channel2 global flag.
* @arg DMA2_FLAG_TC2: DMA2 Channel2 transfer complete flag.
* @arg DMA2_FLAG_HT2: DMA2 Channel2 half transfer flag.
* @arg DMA2_FLAG_TE2: DMA2 Channel2 transfer error flag.
* @arg DMA2_FLAG_GL3: DMA2 Channel3 global flag.
* @arg DMA2_FLAG_TC3: DMA2 Channel3 transfer complete flag.
* @arg DMA2_FLAG_HT3: DMA2 Channel3 half transfer flag.
* @arg DMA2_FLAG_TE3: DMA2 Channel3 transfer error flag.
* @arg DMA2_FLAG_GL4: DMA2 Channel4 global flag.
* @arg DMA2_FLAG_TC4: DMA2 Channel4 transfer complete flag.
* @arg DMA2_FLAG_HT4: DMA2 Channel4 half transfer flag.
* @arg DMA2_FLAG_TE4: DMA2 Channel4 transfer error flag.
* @arg DMA2_FLAG_GL5: DMA2 Channel5 global flag.
* @arg DMA2_FLAG_TC5: DMA2 Channel5 transfer complete flag.
* @arg DMA2_FLAG_HT5: DMA2 Channel5 half transfer flag.
* @arg DMA2_FLAG_TE5: DMA2 Channel5 transfer error flag.
* @retval The new state of DMAy_FLAG (SET or RESET).
返回值 SET RESET
4. DMA中断设置 DMA_ITConfig
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);
参数2 DMA_IT 可选以下参数
5. 中断状态查询
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
参数: 和上一节的一样
返回值 SET RESET
网友评论