Author: jettmin 2024-02-18

DMA的使用

Direct memory access可不依靠CPU进行数据的传输,所以当进行DMA数据传输时和CPU同时独立进行。

使用方法#

DMA一般与其他外设协调使用:

  1. ADC使用DMA提高数据采集的效率、降低CPU负载、减少数据丢失,并支持连续数据采集等;
  2. SPI、I2C、UART 和 SDIO 通过使用 DMA 来提高数据传输效率、降低 CPU 负担;
  3. TMR(定时器)与 DMA 结合的作用主要是实现定时触发的数据传输操作,从而降低 CPU 的负担、提高系统的效率和性能,以及满足实时性要求高的应用场景需求。

配置步骤#

  1. 设置外设地址
  2. 设置存储器地址
  3. 配置数据传输量
  4. 配置通道设定:
    • 通道优先级
    • 数据传输方向
    • 数据传输宽带
    • 地址增量模式
    • 循环模式
    • 存储器到存储器模式
  5. 使能该通道的DMA传输
    void DMA_Configuration(void)
    {
    DMA_InitType DMA_InitStructure;
    DMA_Reset(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->RDOR; // DMA外设ADC基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&s_ad_value; // DMA内存基地址
    DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC; // 内存作为数据传输的目的地
    DMA_InitStructure.DMA_BufferSize = CH_NUM*CONV_NUM; // DMA通道的DMA缓存的大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; // 外设地址寄存器不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; // 内存地址寄存器递增
    DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_HALFWORD; // 数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_HALFWORD; // 数据宽度为16位
    DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; // 工作在循环缓存模式
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; // DMA通道 x拥有高优先级
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; // DMA通道x没有设置为内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure); // 根据DMA_InitStruct中指定的参数初始化DMA的通道
    /* Enable DMA1 channel1 */
    DMA_ChannelEnable(DMA1_Channel1, ENABLE);
    }

注意事项#

DMA传输与CPU进程同时进行,注意DMA传输数据对CPU进程中任务的影响。