【超详细】DMA操作

DMA操作

DMA直接存储器访问,,DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟的一条直接传输数据的通路,极大的提高CPU的使用效率。
STM32F407最多有2个DMA控制器,两个DMA控制器总共有16个数据流,每个通道专门用来管理来自一个或多个外设对存储器访问的请求,还有一个仲裁器来协调各个DMA请求的优先权。

序号DMA有以下特性
1双 AHB 主总线架构,一个用于存储器访问,另一个用于外设访问
2仅支持 32 位访问的 AHB 从编程接口
3每个 DMA 控制器有 8 个数据流,每个数据流有多达 8 个通道(请求)
4每个数据流有单独的四级 32 位先进先出存储器缓冲区(FIFO),可用于 FIFO 模式或直接模式
5通过硬件可以将每个数据流配置为:支持外设到存储器、存储器到外设和存储器到存储器传输的常规通道;支持在存储器方双缓冲的双缓冲区通道
68 个数据流中的每一个都连接到专用硬件 DMA 通道(请求)
7DMA 数据流请求之间的优先级可用软件编程(4 个级别:非常高、高、中、低),在软件优先级相同的情况下可以通过硬件决定优先级(例如,请求 0 的优先级高于请求 1)
8每个数据流也支持通过软件触发存储器到存储器的传输(仅限 DMA2 控制器)
9可供每个数据流选择的通道请求数多达 8 个。此选择可由软件配置,允许多个外设启动DMA 请求
10要传输的数据项的数目可以由 DMA 控制器或外设管理:,DMA 流控制器:要传输的数据项的数目是 1 到 65535,可用软件编程;外设流控制器:要传输的数据项的数目未知并由源或目标外设控制,这些外设通过硬件发出传输结束的信号
11独立的源和目标传输宽度(字节、半字、字):源和目标的数据宽度不相等时,DMA自动封装/解封必要的传输数据来优化带宽。这个特性仅在 FIFO 模式下可用
12对源和目标的增量或非增量寻址
13⑬ 支持 4 个、8 个和 16 个节拍的增量突发传输。突发增量的大小可由软件配置,通常等于外设 FIFO 大小的一半
14每个数据流都支持循环缓冲区管理
155 个事件标志(DMA 半传输、DMA 传输完成、DMA 传输错误、DMA FIFO 错误、直接模式错误),进行逻辑或运算,从而产生每个数据流的单个中断请求

DMA各数据流通道映射表

DMA2
DMA2数据流映射表

DMA的常用函数接口

函数名作用
HAL_DMA_Init用于初始化 DMA1,DMA2

DMA示例配置流程

  1. 使能DMA的时钟;
  2. 初始化DMA;
  3. 使能串口的DMA发送,启动传输;
  4. 查询DMA传输状态;
  5. DMA中断使用方法。

DMA配置示例

void dma_init(DMA_Stream_TypeDef *dma_stream_handle, uint32_t ch)
{
    if((uint32_t)dma_stream_handle > (uint32_t)DMA2)    //得到当前的stream是属于DMA2还是DMA1
    {
        __HAL_RCC_DMA2_CLK_ENABLE();                    //使能DMA2的时钟
    }else{
        __HAL_RCC_DMA1_CLK_ENABLE();
    }
    __HAL_LINKDMA(&g_uart1_handle, hdmatx, g_dma_handle);    //将DMA与USAER1串口联系起来
    
    /* Tx DMA配置 */
    g_dma_handle.Instance = dma_stream_handle;                    /* 数据流选择 */
    g_dma_handle.Init.Channel = ch;                               /* DMA通道选择 */
    g_dma_handle.Init.Direction = DMA_MEMORY_TO_PERIPH;           /* 存储器到外设 */
    g_dma_handle.Init.PeriphInc = DMA_PINC_DISABLE;               /* 外设非增量模式 */
    g_dma_handle.Init.MemInc = DMA_MINC_ENABLE;                   /* 存储器增量模式 */
    g_dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;  /* 外设数据长度:8位 */
    g_dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;     /* 存储器数据长度:8位 */
    g_dma_handle.Init.Mode = DMA_NORMAL;                          /* 外设流控模式 */
    g_dma_handle.Init.Priority = DMA_PRIORITY_MEDIUM;             /* 中等优先级 */
    g_dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;            /* 关闭FIFO模式 */
    g_dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;    /* FIFO阈值配置 */
    g_dma_handle.Init.MemBurst = DMA_MBURST_SINGLE;               /* 存储器突发单次传输 */
    g_dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE;            /* 外设突发单次传输 */

    HAL_DMA_DeInit(&g_dma_handle);
    HAL_DMA_Init(&g_dma_handle);
}

调用DMA传输

HAL_UART_Transmit_DMA(&g_uart1_handle, “正在使用DMA传输”, SEND_BUF_SIZE); 

传输完成后清除标志位

if (__HAL_DMA_GET_FLAG(&g_dma_handle, DMA_FLAG_TCIF3_7))        /* 等待DMA2_Stream7传输完成 */
                {
                    __HAL_DMA_CLEAR_FLAG(&g_dma_handle, DMA_FLAG_TCIF3_7);      /* 清除DMA2_Stream7传输完成标志 */
                    HAL_UART_DMAStop(&g_uart1_handle);      /* 传输完成以后关闭串口DMA */
                    break;
                }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值