F407_18_DMA

在这里插入图片描述

DMA: Direct Memorty Access, 直接存储器访问(控制器);
STM32F407 has 2 DMA;
DMA传输3要素:
1> 传输源:
2> 传输目标:
3> 触发信号
#传输模式:
1> 存储器 -> 存储器;
2> 存储器 -> 外设;
3> 外设 -> 存储器;



1> DMA框图解析

1


2

  • DMA控制器2,连接到AHB上,因此可以实现,存储器 to 存储器的连接;

2


1.1>DMA请求通道选择

外设DMA请求数量多,因此分2个DMA控制器来处理,每个控制器有8X8=64个通道选择;

1
2

  • DMA2中可以把空白没指定的数据流和通道设置为内存to内存模式;

1.2> 仲裁器(Arbiter)

管理8个输入流,设置优先级;


1.3> FIFO(First In First Out)

1.3.1> FIFO框图

1

1.3.2> FIFO特性

1> 是存储器;
2> 存储的数据先进先出,类似水管;
3> 无需读写地址,操作简单;

1.3.3> FIFO大小

STM32F407中FIFO大写为:4-word FIFO

1

处理输入输出宽度不同数据:
字节进,字出(4个字节);
字节进,半字出(2个字节);
半字进,字出;
半字进,字节出;

1.4> 突发增量(burst Size):

1111

一次写进FIFO的字节数:
Single:1Byte;
4 Increment:4Byte;
8 Increment:8Byte;
16 Increme:16Byte;
!注意:选择FIFO的 Threshold;

1.5> 存储器接口:

连接到:Flash,SRAM;

1.6> 存储器接口:

连接到:外设,UART,定时器,SPI控制器等;

1.7> 编程接口:

DMA控制器也是一个器件,Cotrex-M4通过编程接口,配置他;



2> DMA结构体

2.1> 句柄结构体

typedef struct __DMA_HandleTypeDef
{
  DMA_Stream_TypeDef         *Instance;		// DMA外设基地址;                                                     
  DMA_InitTypeDef            Init;          // 初始化结构体;                                                   
  HAL_LockTypeDef            Lock;			// 资源锁                                                   
  __IO HAL_DMA_StateTypeDef  State;			// 传输状态                                                            
  void                       *Parent;		// 指向外设句柄,这样存储器与外设就链一块了;                                                    

  /* DMA 传输完成回调函数 */
  void                       (* XferCpltCallback)( struct __DMA_HandleTypeDef * hdma);         

   /* DMA 传输半完成回调函数 */
  void                       (* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);     
  
  /* 存储器1 DMA传输完成回调函数  */
  void                       (* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma);       

   /* 存储器1 DMA传输半完成回调函数 */
  void                       (* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * h
  
   /* DMA传输错误回调函数    */
  void                       (* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);        
  
   /* DMA传输取消回调函数    */
  void                       (* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);       

  __IO uint32_t              ErrorCode;      // 错误代码                                                  
  uint32_t                   StreamBaseAddress;  // DMA数据流基地址                                               
  uint32_t                   StreamIndex;	// DMA 数据流编号                                                   
}DMA_HandleTypeDef;

2.2> 初始化结构体

typedef struct
{
  uint32_t Channel;		// 通道选择  通道0~7;
  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;

Direction: 3种传输方向

#define DMA_PERIPH_TO_MEMORY          0x00000000U                 /*!< Peripheral to memory direction */
#define DMA_MEMORY_TO_PERIPH          ((uint32_t)DMA_SxCR_DIR_0)  /*!< Memory to peripheral direction */
#define DMA_MEMORY_TO_MEMORY          ((uint32_t)DMA_SxCR_DIR_1)  /*!< Memory to memory direction     */

突发是怎么回事?

2.3> DMA结构体

typedef struct
{
  __IO uint32_t CR;     /*!< DMA stream x configuration register      */
  __IO uint32_t NDTR;   /*!< DMA stream x number of data register     */
  __IO uint32_t PAR;    /*!< DMA stream x peripheral address register */
  __IO uint32_t M0AR;   /*!< DMA stream x memory 0 address register   */
  __IO uint32_t M1AR;   /*!< DMA stream x memory 1 address register   */
  __IO uint32_t FCR;    /*!< DMA stream x FIFO control register       */
} DMA_Stream_TypeDef;


3> 实验_存储器to存储器

实现2个数组拷贝,类似memcpy(void *str1, const void *str2, size_t n)

Step 1> 初始化配置:

/* DMA_Exported_Functions_Group1 Initialization */
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma); 


Step 2> 启动DMA:


#define DMA_SxCR_DBM_Pos         (18U)                                         
#define DMA_SxCR_DBM_Msk         (0x1UL << DMA_SxCR_DBM_Pos)       /*!< 0x00040000 */
#define DMA_SxCR_DBM             DMA_SxCR_DBM_Msk 




/* 启动DMA */
HAL_DMA_Start();  // 程序员用
     |
    调用
     |
     V
DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
	/* SteP1 : Clear DBM bit */
	hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
  
	/*Step 2: Configure DMA Stream data length */
	hdma->Instance->NDTR = DataLength;    // Number of Data Register

 	/*Step 3: Configure DMA Stream source address */
 	hdma->Instance->PAR = SrcAddress;

    /*Step 4: Configure DMA Stream destination address */
    hdma->Instance->M0AR = DstAddress;

}



Step 3> 等待传输完成;为什么需要这个?延时函数替代行不?

#define DMA_FLAG_TCIF0_4              0x00000020U

HAL_DMA_PollForTransfer()
{
	mask_cpltlevel = DMA_FLAG_TCIF0_4 << hdma->StreamIndex;

	regs = (DMA_Base_Registers *)hdma->StreamBaseAddress;
	tmpisr = regs->ISR;

	while(((tmpisr & mask_cpltlevel) == RESET) && ((hdma->ErrorCode & HAL_DMA_ERROR_TE) == RESET))
}

4> 实验_存储器to外设

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值