×
单片机 > 其他资讯 > 详情

13-HAL库DMA系统总结

发布时间:2020-07-10 发布时间:
|

1.间接


DMA:Direct Memory Access,直接存储访问,实现数据在外设与存储器或存储器之间高速访问,数据移动过程无需CPU操作控制,因此可以大大解放CPU负担。


外设(ADC、SPI、I2C、DCMI等外设的数据寄存器),存储器(片内SRAM、外部存储器、片内Flash等等)。外设到存储器,例如将AD转换的数据转移到所定义的存储区中。存储器到外设多用于外设的发送通信,例如串口不定长数据的输入输出。

STM32F7xx系列有2个DMA控制器,每个控制器具有8个数据流(stream),每个数据流有8个通道(channel),对应如下:


每个外设请求占用一个数据流通道,相同外设请求可以占用不同数据流通道。数据流的传输依靠仲裁器进行管理和判断,包括软件(例如初始化中mydma2.Init.Priority=DMA_PRIORITY_MEDIUM)和硬件(数据流编号越低,优先权越高)。DMA传输有FIFO模式和直接模式,直接模式在每个外设请求时立即启动对存储器传输,FIFO模式为源数据传输到目标地址前将数据临时存放在FIFO(先进先出存储器缓冲区)中。FIFO模式对于要求源地址和目标地址数据宽度不同时很有用,同时可用于突发传输。


存储器到存储器传输必须使用DMA2,但对数据流编号和通道没有硬性要求。


DMA2的存储器端口和外设端口都连接到AHB,但DMA的存储区端口没有AHB2外设的访问权,同时外设端口只连接到APB1外设,所以DMA1不能实现存储器到存储器传输。


2.DMA相关函数解析


关于DMA,ST官方提供了HAL库(封装函数)和LL库(直接操作寄存器)。和GPIO定义类似,需要先使能相关时钟,定义句柄结构体DMA_HandleTypeDef mydma2,随后进行DMA的各项配置,最后进行初始化。


typedef struct __DMA_HandleTypeDef

    DMA_Stream_TypeDef          *Instance;                                                    

    DMA_InitTypeDef              Init;                                                         

    HAL_LockTypeDef              Lock;                                                         

    __IO HAL_DMA_StateTypeDef    State; 

    void                        *Parent;

    void                   (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma); 

    void                   (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);

    void                   (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma); 

    void                   (* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * hdma); 

    void                   (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);  

    void                   (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma); 

    __IO uint32_t                ErrorCode; 

    uint32_t                     StreamBaseAddress; 

    uint32_t                     StreamIndex; 

}DMA_HandleTypeDef;

typedef struct

   uint32_t     Channel;               //通道

   uint32_t     Direction;             //方向

   uint32_t     PeriphInc;             //外设递增

   uint32_t     MemInc;                //内存递增

   uint32_t     PeriphDataAlignment;   //外设数据宽度

   uint32_t     MemDataAlignment;      //内存数据宽度

   uint32_t     Mode;                  //模式选择

   uint32_t     Priority;              //优先级

   uint32_t     FIFOMode;              //FIFO模式

   uint32_t     FIFOThreshold;         //FIFO阈值

   uint32_t     MemBurst;              //内存突发传输

   uint32_t     PeriphBurst;           //外设突发传输

}DMA_InitTypeDef;

3.DMA初始化及配置


HAL库中,基本上都是结合XXX_HandleTypeDef 结构体和XXX_InitTypeDef 结构体进行初始化配置。


#include "dma.h"

#include "stm32f7xx_hal.h"

 

uint32_t DMA_Result;

DMA_HandleTypeDef Mydma1;

 

void MyDMA_Config(void){

__HAL_RCC_DMA2_CLK_ENABLE();    //时钟使能

Mydma1.Instance=DMA2_Stream0;       //数据流

Mydma1.Init.Channel=DMA_CHANNEL_0;   //通道

Mydma1.Init.Direction=DMA_PERIPH_TO_MEMORY;    //传输方向

Mydma1.Init.PeriphInc=DMA_PINC_DISABLE;  //外设是否递增

Mydma1.Init.MemInc=DMA_MINC_DISABLE;    //内存是否递增

Mydma1.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;   //外设数据宽度半个字节

Mydma1.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;   //内存数据宽度半个字节

Mydma1.Init.Mode=DMA_CIRCULAR;    //循环模式

Mydma1.Init.Priority=DMA_PRIORITY_MEDIUM;   //优先级中等

Mydma1.Init.FIFOMode=DMA_FIFOMODE_DISABLE;  //是否使能FIFO模式

Mydma1.Init.PeriphBurst=DMA_PBURST_SINGLE;  //外设突发传输

Mydma1.Init.MemBurst=DMA_MBURST_SINGLE;     //内存突发传输

HAL_DMA_Init(&Mydma1);    //初始化

HAL_DMA_Start(&Mydma1,ADC1_BASE,DMA_Result,2400);   //启动DMA

}

随后还需进行相关外设的配置:如串口,AD采样等。


4.DMA中断


中断配置,中断函数调用,回调函数覆盖。

 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
详解漏电保护器的工作原理