Skip to content

DMA直接存储访问控制器

用于外设和存储器之间, 或者存储器和存储器之间提供高速的数据传输, 节省CPU的资源

DMA是一个独立的外设, 直接连接在总线矩阵之上, 所以可以访问所有的外设

  • DMA请求
  • 通道的选择
  • 数据搬运的地址

F4, F7添加了一个FIFO的功能, 主要是为了对数据长度不同处理, 以及进行暂存数据

传输方向, 传输的对象, DMA传输的时候也有一个优先级, 确定传输数据双方的数据格式, 传输的时候是否需要循环传输, 是否需要传输的中断/标志

传输的使能需要由别的外设发起

  • 升级

双缓冲模式, DMA在两个内存区域之间进行切换, 与此同时CPU对填充结束的区域进行操作

FIFO: FIFO随着源目标和目标数据宽度不同的的时候进行使用, 比如8bit-32bit

单次传输: 批量传输数据, AHB总线的外设设置为单次传输的时候, 每一个DMA请求产生一个一字节, 半字节或者字的传输

突发传输: 每一个字节产生4个, 8个或16个节拍的字节, 半字节或者字的传输

主要是针对FIFO进行的设置, FIFO的容量为16byte, 实际上就是一个阈值, 当FIFO填充到一定情况的时候, 一次传输出去特定数量的字节数

DMA请求复用器(DMAMUX), 由于请求的数量以及格式多样化, 使用复用器就不再是一一对应的

c
typedef struct __DMA_HandleTypeDef
{
  DMA_Channel_TypeDef        *Instance;                                                    /*!< Register base address                  */
  
  DMA_InitTypeDef            Init;                                                         /*!< DMA communication parameters           */
  
  HAL_LockTypeDef            Lock;                                                         /*!< DMA locking object                     */
  
  __IO HAL_DMA_StateTypeDef  State;                                                        /*!< DMA transfer state                     */
  
  void                       *Parent;                                                      /*!< Parent object state                    */
  
  void                       (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);     /*!< DMA transfer complete callback         */
  
  void                       (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); /*!< DMA Half transfer complete callback    */
  
  void                       (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer error callback            */

  void                       (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);    /*!< DMA transfer abort callback            */
  
  __IO uint32_t              ErrorCode;                                                    /*!< DMA Error code                         */

  DMA_TypeDef                *DmaBaseAddress;                                             /*!< DMA Channel Base Address               */
  
  uint32_t                   ChannelIndex;                                                /*!< DMA Channel Index                      */

} DMA_HandleTypeDef;

这里面有一个指向寄存器的结构体, 一个初始化结构体, 还有一些回调函数的结构体, 会在中断中被调用