DMA外设

文章目录

  • DMA外设
    • DMA外设结构
    • 初始化流程
    • 标准库函数使用模板
      • DMA初始化函数模板
      • DMA配置函数
      • DMA中断函数
    • 流程图

DMA外设

DMA(Direct Memory Access)直接存储器存取。
DMA 可以提供外设和存储器或者存储器和存储器之间的高速数据传输,无须 CPU 干预,节省了 CPU 的资源。
12 个独立可配置的通道,每个通道都传输的数据量最大为 65535。
每个通道都支持软件触发和特定的硬件外设触发。
STM32F103C8T6 DMA资源:DMA1(7个通道)

DMA外设结构

DMA外设_第1张图片

  1. 从外设数据寄存器 或者 从当前外设/存储器地址寄存器 指示的存储器地址取数据,第一次传输时的开始地址为DMA_CPARx 或 DMA_CMARx寄存器 指定的外设基地址或存储器单元。
  2. 存数据到 外设数据寄存器 或者 当前外设/存储器地址寄存器 指示的存储器地址,第一次传输时的开始地址是DMA_CPARx 或 DMA_CMARx寄存器 指定的外设基地址或存储器单元。
  3. 执行一次(DMA_CNDTRx寄存器)自减操,该寄存器包含未完成的操作数目。
  4. 产生中断,置DMA标志位(需软件清除)。。。

DMA总线:DMA1(7通道)和DMA2(5通道)。以太网模块含一条私有的DMA总线。
DMA控制器:处理DMA请求。当DMA控制器开始访问发出请求的外设时,DMA控制器立即发送给它一个应答信号。当外设得到应答信号时,外设立即释放它的请求,同时DMA控制器撤销应答信号。
仲裁器:根据通道请求的优先级来启动外设/存储器的访问(编号低的通道优先级高)。
c总线矩阵:左边为主动单元(拥有存储器的访问权),右边为被动单元(只能被主动单元读写),也可进行DMA与CPU的访问优先级处理。
AHB从设备:连接在AHB总线上,包含DMA配置寄存器等。

传输的数据宽度不一致的时,高位抹去或补零,低位不变。

增量模式:下个要传输的地址为前一个地址加上增量值(自增数据宽度为1,2,4)
循环模式:数据传输数目为0时,自动恢复为初始值(类似ADC扫描模式)
M2M模式:由软件触发的DMA请求(不能与循环模式一起用)
外设到存储器模式:由外设触发的DMA请求
中断:可在DMA传输过半、传输完成、传输错误时发生中断

触发DMA的通道:
DMA1触发通道表
DMA外设_第2张图片
DMA2触发通道表
DMA外设_第3张图片

DMA结构简图
DMA外设_第4张图片

初始化流程

  • RCC:同前开启RCC_AHBPeriph_DMA1
  • DMA初始化结构体:DMA_InitTypeDef
    • DMA_PeripheralBaseAddr:(外设)的起始地址
    • DMA_PeripheralDataSize:(外设)的数据宽度(word/halfword/byte)
    • DMA_PeripheralInc:(外设)的是否自增
    • DMA_MemoryBaseAddr:(存储器)的起始地址
    • DMA_MemoryDataSize:(存储器)的数据宽度(word/halfword/byte)
    • DMA_MemoryInc:(存储器)是否自增
    • DMA_DIR:传输方向
    • DMA_BufferSize:传输计数器
    • DMA_Mode:模式(是否自动重装)
    • DMA_M2M:硬件触发/软件触发
    • DMA_Priority:优先级
  • DMA先关闭:DMA_Cmd(DMA1_Channel1, DISABLE)

标准库函数使用模板

DMA初始化函数模板

uint16_t MyDMA_Size;

void MyDMA_Init(uint32_t AddrA, uint32_t AddrB, uint16_t Size)
{
	MyDMA_Size = Size;
	
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	DMA_InitTypeDef DMA_InitStructure;
	DMA_InitStructure.DMA_PeripheralBaseAddr = AddrA;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
	DMA_InitStructure.DMA_MemoryBaseAddr = AddrB;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = Size;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1, DISABLE);
}

void MyDMA_Transfer(void)
{
	DMA_Cmd(DMA1_Channel1, DISABLE);//先关闭DMA
	DMA_SetCurrDataCounter(DMA1_Channel1, MyDMA_Size);//传输计数器reset
	DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMA
	
	while (DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET);//等待转运完成
	DMA_ClearFlag(DMA1_FLAG_TC1);//清除标志位
}

DMA配置函数

/* DMA_SetCurrDataCounter         配置传输计数器
* @ param1  选择DMAx
* @ param2  计数器的数值
* @ retval  None
*/
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); 

/* DMA_GetCurrDataCounter         获取传输计数器
* @ param1  选择DMAx
* @ retval  计数器的数值
*/
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);

/* DMA_GetFlagStatus              检测DMAx的通道的标志事件()
* @ param1  DMAx通道和标志选择
* @ retval  事件标志
*/
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);

/* DMA_ClearFlag                  清除DMAx的通道的标志事件
* @ param1  DMAx通道和标志选择
* @ retval  None
*/
void DMA_ClearFlag(uint32_t DMAy_FLAG);

DMA中断函数

//使能/失能DMA中断
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);
//获取DMA中断状态
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
//清除DMA中断标志位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);

流程图

      
           +--------+                      +--------+
           |  外设  |                      | 存储器 |
           |起始地址|                      |起始地址|
           |数据宽度|                      |数据宽度|
           |是否自增|                      |是否自增|
           +--------+        +----+        +--------+
            			     |方向|
          				     +----+		   +-------+
            +----------+------------------>| Flash-+---+
            |外设寄存器|                   |       |   |
            +----------+<------------------+ SRAM <+---+
       		    				^          +-------+
          					    |
       						    |
                           +----+-----+      +----------+
                           |传输计数器|<-----+自动重装器|
                           +----------+      +----------+
                                ^
                                |
                            +---+---+
                            |0 M2M 1|
                            +-------+
              +--------+     ^     ^     +--------------+
              |硬件触发+-----+     +-----+软件触发(连续)|
              +--------+                 +--------------+
  


                                     ------ BY Flier

2023.9.6

Reference:江协科技、《stm32f10x用户手册》、《stm32库开发实战指南教程》

文章目录

  • DMA外设
    • DMA外设结构
    • 初始化流程
    • 标准库函数使用模板
      • DMA初始化函数模板
      • DMA配置函数
      • DMA中断函数
    • 流程图

你可能感兴趣的:(#,标准库,单片机,嵌入式硬件,stm32)