当前位置: 首页 > news >正文

20、DMA----释放CPU压力,加快传输

1、DMA介绍

DMA,全称为:Direct Memory Access,即直接存储器访问。DMA传输方式无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,能使CPU的效率大为提高。

STM32F103内部有2个DMA控制器(DMA2仅存大容量产品中),DMA1有7个通道,DMA2有5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求,一个仲裁器来协调各个DMA请求的优先权。

DMA有以下特性

  • 每个通道都直接连接专用的硬件DMA请求,每个通道都支持软件触发。通过软件来配置。
  • 优先权可以通过软件编程设置,有四个等级:很高、高、中、低,优先权相同时由硬件决定。
  • 独立源和目标数据区的传输宽度,可以根据字节、半字、全字,模拟打包和拆包过程。源和目标地址必须按照数据传输宽度对齐。
  • 支持循环的缓冲器管理。
  • 每个通道有3个事件标志:DMA半传输、DMA传输完成、DMA传输出错,3个事件标志逻辑或成为一个独立中断请求。
  • 存储器和存储器间的传输。
  • 外设和存储器,存储器和外设的传输。
  • 闪存、SRAM、外设SRAM、APB1、APB2、AHB外设都可以作为访问的源和目标。
  • 最大传输数目:65536

1.1、DMA框图

STM32F103ZET6有两个DMA控制器,DMA1和DMA2。

  • ①DMA请求: 外设想要通过DMA来传输数据,必须先给DMA控制器发送DMA请求,DMA收到请求信号后,控制器会给外设一个应答信号,当外设应答后且DMA控制器收到应答信号后,就会启动DMA传输,直到传输完毕。
  • ②通道:DMA具有12个独立可编程的通道,其中DMA1有7个通道,DMA2有5个通道,每个通道对应不同的外设的DMA请求。虽然每个通道可以接收多个外设的请求,但是同一时间只能接收一个,不能同时接收多个。
  • ③仲裁器:当发生多个DMA通道请求时,就会由仲裁器管理,仲裁器管理DMA通道请求分为两个阶段。第一阶段属于软件阶段,可以在DMA_CCRx寄存器中设置,有4个等级:非常高,高,中和低四个优先级。第二阶段属于硬件阶段,两个或以上的DMA通道请求设置的优先级一样,则他们优先级取决于通道编号,编号越低优先权越高,比如通道0高于通道1。DMA1控制器拥有高于DMA2控制器的优先级。

1.2、DMA请求映射表

2、DMA函数

DMA_HandleTypeDef结构体类型指针变量:

typedef struct __DMA_HandleTypeDef
{void                                *Instance;      /* 寄存器基地址 */DMA_InitTypeDef                     Init;           /* DAM 通信参数 */HAL_LockTypeDef                     Lock;           /* DMA 锁对象 */ __IO HAL_DMA_StateTypeDef           State;          /* DMA 传输状态 */ void                                *Parent;        /* 父对象状态,HAL库处理的中间变量 */ void(*XferCpltCallback)( struct __DMA_HandleTypeDef *hdma);    /*DMA传输完成回调*/ void(* XferHalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);/* DMA一半传输完成回调 */void(* XferM1CpltCallback)( struct __DMA_HandleTypeDef * hdma); /* DMA传输完整的Memory1回调 */void(* XferM1HalfCpltCallback)( struct __DMA_HandleTypeDef * hdma);/* DMA传输半完全内存回调 */void(* XferErrorCallback)( struct __DMA_HandleTypeDef * hdma);/*DMA传输错误回调*/void(* XferAbortCallback)( struct __DMA_HandleTypeDef * hdma);/* DMA传输中止回调 */__IO uint32_t                       ErrorCode;              /* DMA存取错误代码 */DMA_TypeDef                         *DmaBaseAddress;        /* DMA通道基地址 */uint32_t                            ChannelIndex;           /* DMA通道索引 */ 
}DMA_HandleTypeDef;

  • Instance:是用来设置寄存器基地址,如果设置的对象是串口1的发送,串口1的DMA传输需要用到的是DMA1的通道4,即DMA1_Channel4。
  • Parent:是HAL库处理中间变量,用来指向DMA通道外设句柄。
  • XferCpltCallback:传输完成回调函数入口地址
  • XferHalfCpltCallback:半传输完成回调函数入口地址
  • XferM1CpltCallback:Memory1传输完成回调函数入口地址
  • XferErrorCallback:传输错误回调函数入口地址
  • Init:它是DMA_InitTypeDef结构体类型变量
typedef struct 
{    uint32_t Direction;               /* 传输方向,例如存储器到外设DMA_MEMORY_TO_PERIPH */  uint32_t PeriphInc;               /* 外设(非)增量模式,非增量模式DMA_PINC_DISABLE */   uint32_t MemInc;                  /* 存储器(非)增量模式,增量模式DMA_MINC_ENABLE */   uint32_t PeriphDataAlignment;     /* 外设数据大小:8/16/32位 */ uint32_t MemDataAlignment;        /* 存储器数据大小:8/16/32位 */ uint32_t Mode;                    /* 模式:循环模式/普通模式 */     uint32_t Priority;                /* DMA优先级:低/中/高/非常高 */  
}DMA_InitTypeDef;
  • HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma);DMA的初始化函数
  • __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA1时钟使能 */ __HAL_RCC_DMA2_CLK_ENABLE(); /* DMA2时钟使能 */
  • __HAL_LINKDMA(&g_uart1_handler, hdmatx, g_dma_handle);连接DMA和外设句柄。
  • 外设的DMA发送、启动传输函数。
  • __HAL_DMA_GET_FLAG(&g_dma_handle, DMA_FLAG_TC4);查询DMA传输通道的状态
  • __HAL_DMA_GET_COUNTER(&g_dma_handle);获取当前传输剩余数据量
  • __HAL_DMA_SET_COUNTER (&g_dma_handle, 1000);设置对应的DMA数据流传输的数据量大小
  • DMA中断函数
    • DMA中断对于每个通道都有一个中断服务函数
    • HAL库提供了通用DMA中断处理函数HAL_DMA_IRQHandler, 在该函数内部,会对DMA传输状态进行分析,然后调用相应的中断处理回调函数:
      • 发送完成回调函数
      • 发送一般回调函数
      • 接收完成回调函数
      • 接收一半回调函数
      • 传输错误回调函数
http://www.dtcms.com/a/350549.html

相关文章:

  • 滚珠丝杆升降机的多台联动使用方案可以应用哪些领域
  • [pilot智驾系统] 自动驾驶守护进程(selfdrived)
  • linux - jvm相关命令
  • 操作系统中,进程与线程的定义与区别
  • 雷卯针对香橙派Orange 4G-IOT开发板防雷防静电方案
  • `lock()` 和 `unlock()` 线程同步函数
  • THM Bricks Heist靶机
  • Java 学习笔记(基础篇10)
  • HTML应用指南:利用POST请求获取全国三星门店位置信息
  • 【目标跟踪】《FastTracker: Real-Time and Accurate Visual Tracking》论文阅读笔记
  • 目前城投债
  • MySQL常见报错分析及解决方案总结(1)---Can‘t connect to MySQL server on ‘localhost‘(10061)
  • Docker:技巧汇总
  • 利用matlab实现CST超表面阵列的自动建模
  • 数据结构:单链表(详解)
  • SSL移动接入方案和移动资源发布
  • 【学习笔记】怎么解决/dev/sda3: clean, XXX files, XXX blocks
  • 【Wrangler(Cloudflare 的官方 CLI)和 npm/npx 的区别一次讲清】
  • SpringCloud微服务技术自用笔记
  • day52_2025-08-25
  • 【猿人学】web第一届 第13题 入门级 cookie
  • 【动态规划】卡特兰数
  • 文件读取结束的判定方法:正确使用feof函数避免文件读取错误
  • CAN总线详解(四)CANFD报文结构
  • 小红书链接uid等批量转换,界面软件工具
  • 【COMSOL】COMSOL帮助文档无法打开的解决办法
  • 智能专网升级:4G与5G混合组网加速企业数字化转型
  • leetcode算法刷题的第十七天
  • 房地产模式的运行逻辑与内在风险
  • Acrobat DC 中的条件格式化