直接存储器存取(DMA):用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传 输,节省了CPU的资源。   (可以理解与两个存储数据地方中间的顺丰搬运工;也可以理解为一根管道)

一.关于DMA通道

STM32F10xxx中一共有12个通道,其中DMA1有7个通道,DMA2有5个通道

可以对应手册,来找到不同DMA或不同通道连接的外设。

注意:只有在外设和存储器间需要传输数据时才需要遵循上面两个表,而存储器和存储器间的传输是不需要管什么什么通道的。

二.关于DMA传输方向

DMA和快递运输的本质其实差不多,只不过DMA可以是双向的。

  1. 存储器和存储器间(DMA_MEMORY_TO_MEMORY)
  2. 外设到存储器(DMA_PERIPH_TO_MEMORY)
  3. 存储器到外设(DMA_MEMORY_TO_PERIPH)
  4. 闪存、 SRAM、外设的SRAM、 APB1、 APB2和AHB外设均可作为访问的源和目标。

三.DMA模式

  1. Normal(常规模式)
  2. Circular(循环模式)

简单来说这两种模式最大的区别就是等到数据传输的数目变为0时,会不会自动进行下一次数据传输(或者说是数据传输的数目的填充)。显然在Normal模式中,Start之后,当传输完一组数据,就要重新配置数据传输的数目(即下列代码中寄存去CNDTR的值)

hdma_memtomem_dma1_channel1.Instance->CNDTR=数据传输的数目;
__HAL_DMA_DISABLE(&hdma_memtomem_dma1_channel1);

以上两个代码适合常规模式中重新使能DMA而再次使用。(这里我初始化的是存储器和存储器间及通道1,要根据自己的情况将相关变量或者宏定义进行更改)

四.DMA传输地址

  1. SRCAddress(源地址)——地址可递增可递减(需要配置)
  2. DESTAddress(目标地址)——地址可递增可递减(需要配置)
  • 显然,无论是什么东西的传输都需要至少需要两个地址(一头一尾)
  • 就是类似于一根管道的两端
  • 地址能否配置正确是DMA能否正确传输数据的关键
  • 至于地址可增可减:大部分数据都是连续的(可以理解为数组的遍历),而不是放在某一个单个的地址上,因此需要配置来让DMA传输我们需要的数据,减少麻烦。

    五.DMA传输数据宽度及可编程的数据传输数目

    数据宽度:

    1. 字节Byte——8位
    2. 半字Half Word——16位
    3. 全字Word——32位

    注意:当你的传输数据比较少时,尽量选择小的数据宽度(因为数据宽度越大,数据传输的速度越慢,可以自己通过串口打印来实践)

    可编程的数据传输数目:0~65535

    最后给大家分享常用的几个函数(HAL库)

    __HAL_DMA_GET_FLAG(__HANDLE__, __FLAG__);(获取DMA的传输状态 ing or end)

    __HAL_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__);(清楚传输标志位)

    __HAL_DMA_ENABLE(__HANDLE__);(使能DMA,多用于Normal中的再次使用,记得配合设置数据传输的数目的函数)

    __HAL_DMA_DISABLE(__HANDLE__);

    以上仅为菜B作者的浅层理解,可能并不是很准确、专业,嘻嘻嘻嘻

    祝大家学有所成!

    作者:没有能力就没有责任

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 DMA理论

    发表回复