MCU学习笔记
DMA原理
1. DMA原理
2. DMA相关概念
3. DMA数据流配置过程
4. HAL库配置DMA
1. DMA原理
-
DMA, Direct Memory Access, 即直接存储器访问。无需CPU直接控制,通过硬件为RAM和IO设备开辟一条直接数据传输通道,将数据直接从一个地址空间复制到另一个地址空间,传输动作本身由DMA控制器实现。
-
作用:为CPU减负,提升CPU效率
-
STM32F4/F7: 2个DMA控制器,16个数据流。每个DMA控制器都用于管理一个或者多个外设的额存储器访问请求。每个数据流最多可以有多达8个通道(或请求),每个通道都有一个仲裁器,用于处理DMA请求间的优先级。
-
框图
链接方式:1. 存储器2存储器,2. 存储器2外设,3. 外设2存储器
-
特性
-
8个数据流,每个数据流有最多8个通道(或称请求)
-
每个数据流有单独的四级32位FIFO,可用于FIFO模式或直接模式:
FIFO模式:可以通过软件将阈值级别选取位FIFO大小的1/4,1/2,3/4
直接模式:每个DMA请求会立即启动对存储器的传输。 -
通过硬件可以将每个数据流配置为:1. 存储器2存储器,2. 存储器2外设,3. 外设2存储器,传输的常规通道;2. 也支持在存储器方双缓冲的双缓冲区通道
-
8个数据流中的每一个都连接到专用硬件DMA通道
-
数据流请求之间的优先级可用软件编程(4个级别:非常高,高,中,低),在软件优先级相同的情况下可以通过硬件决定优先级
-
每个数据流支持通过软件触发存储器2存储器的传输(仅限DMA2控制器)
-
软件配置每个数据流选择的通道请求,允许几个外设启动DMA请求
-
要传输的数据项的项目数由DMA控制器或外设管理:
DMA流控制器:要传输的数据项的数:1~65535,可软件编程
外设流控制器:要传输的数据项的数未知,由源或目标外设通过发出传输请求信号控制。 -
独立的源和目标传输宽度:(字节,半字,字),源于目标的数据宽度不相等时,DMA自动封装/解封必要的传输数据来优化带宽。(仅在FIFO模式下可用)
-
对源和目标的增量或非增量寻址
-
支持4,8,16个节拍的增量突发传输。突发增量的大小可由软件配置,通常为外设FIFO大小的一半
-
每个数据流都支持循环缓冲区管理
-
5个事件标志进行逻辑或运算,从而产生每个数据流的单个中断请求(DMA半传输,DMA传输完成,DMA传输错误,FIFO错误,直接模式错误)
-
2. DMA相关概念
-
通道选择
每个DMA请求与一个数据流相关联,请求可以从8个可能的通道请求中被选出。此操作由DMA_SxCR寄存器中的CHSEL[2:0]位控制。 -
DMA事务
DMA事务由给定数目的数据传输序列组成。要传输的数据项的数目,宽度(字节,半字,字)由软件编程。
DMA传输的操作:
从外设数据寄存器或存储单元中加载数据:通过DMA_SxPAR(外设为源)或DMA_SxM0AR(存储器为源)寻址;
将加载的数据存储到外设数据寄存器或存储单元中:通过DMA_SxPAR(外设为目的)或DMA_SxM0AR(存储器为目的)寻址;
DMA_SxNDTR计数器在数据存储结束后递减,该计数器中包含仍需执行的事务数;
传输方向配置:DMA_SxCR.DIR[1:0]位
-
仲裁器
作用:为两个AHB主端口(存储器和外设端口)提供基于请求优先级的8个DMA数据流请求管理,并启动外设/存储器访问序列
优先级管理:
软件:每个数据流优先级可以在DMA_SxCR寄存器中配置。分为四个级别:非常高,高,中,低。
硬件:两个请求的软件优先级相同,则编号低的数据流优先。 -
指针递增
由DMA_SxCR寄存器中的PINC, MINC位控制 ,外设和存储器指针在每次传输后可以自动递增或保持常量。 -
循环模式
由DMA_SxCR寄存器中的CIRC位控制,用于处理循环缓冲区和连续数据流(如ADC扫描模式)。激活循环模式时,要传输的数据项的数目在数据流配置阶段自动用设置的初始值进行加载,并继续响应DMA请求。 -
单次传输和突发传输
DMA控制器可以产生单次传输或者4,8,16个节拍的增量突发传输。
突发大小:软件通过配置DMA_SxCR寄存器中的MBURST[1:0]和PBURST[1:0]位,独立配置两个AHB端口
单次传输:根据DMA_SxCR寄存器PSIZE[1:0]位,每个DMA请求产生一次字节,半字,字的数据传输
突发传输:根据DMA_SxCR寄存器PBURST[1:0], PSIZE[1:0]位的值,每个DMA请求相应的生成4,8,16个节拍的字节,半字,字的数据传输。 -
双缓冲区模式
通过DMA_SxCR寄存器中的DBM位配置。
有两个存储器指针,工作方式与常规数据流相同。
使能双缓冲区模式,将自动使能循环模式,每次事务结束时,交换存储器指针。这样软件再处理一个存储器区域的同事,DMA传输还可以填充/使用第二个粗初期区域。双缓冲区数据流可以双向工作(存储器既可以是源也可以是目标)。 -
DMA中断
对于每个DMA数据流,可在以下事件时产生中断: 达到半传输,传输完成,传输错误,FIFO错误,直接模式错误
3. DMA数据流配置过程
- 若数据流使能,则配置DMA_SxCR.EN将其禁止。然后读取此位,确认没有正在进行的数据流操作。若DMA_SxCR.EN=0,表示可以配置数据流。
- 设置外设基地址:配置DMA_SxPAR寄存器来配置外设端口寄存器地址,、
- 设置存储器基地址:配置DMA_SxMA0R寄存器
- 配置数据的传输方向
- 配置传输的数据项总数:配置DMA_SxNDTR寄存器
- 选择DMA通道:配置DMA_SxCR中的CHSEL[2:0]
- 配置数据流的优先级:配置DMA_SxCR寄存器中的PL[1:0]
- 配置iFIFO
- 激活DMA_SxCR.EN=1位,激活数据流.
4. HAL库配置DMA
-
DMA初始化
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef*hdma);
-
使能DMA传输
HAL_DMA_Start(DMA_HandleTypeDef*hdma, uint32_t SrcAddress, unit32_t DstAddress, uint32_t Datalengh);
HAL_DMA_Start_IT(DMA_HandleTypeDef*hdma, uint32_t SrcAddress, unit32_t DstAddress, uint32_t Datalengh);
- 中断
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef*hdma);
- 等待传输完成
HAL_StatusTypeDef HAL_DMA_PollForeTransfer(DMA_HandleTypeDef*hdma, unit32_t Completelevel, unit32_t Timeout);
- 通用处理函数
void HAL_DMA_IRQHandler(DMA_HandleTypeDef*hdma);
- HAL中DMA配置步骤
- 连接DMA和对应外设
_HAL_LINKDMA(_HANDLE_,_PPP_DMA_FIELD_,_DMA_HANDLE_)
- 使能DMA时钟,复位DMA寄存器
HAL_DMA_DeInit(&UART1TxDMA_Handler);
- 初始化DMA通道参数
- 使能外设DMA传输
- 连接DMA和对应外设
参考资料:正点原子视频 Thanks^^
【注】:个人学习笔记,如有错误,望不吝赐教,这厢有礼了~~~