DMA介绍

一 DMA简介

DMA全称Direct Memory Access, 直译为“直接存储器访问”。
DMA的作用是帮助CPU在内存之间搬运数据,搬运的过程中无需CPU的干涉,也不存在中断方式传送数据的那样保留现场和恢复现场的过程,这样的DMA控制器通过硬件来为RAM和IO设备之间开辟一条直接传送数据的通路(从源地址搬运到目的地址),从而使CPU的负担大大减少。

二 DMA有什么用

直接存储器存取用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

三 数据从什么地方送到什么地方?

外设到SRAM,FLASH(I2C/UART等获取数据并送入SRAM,FLASH);
SRAM的两个区域之间;
外设到外设(ADC读取数据后送到TIM1控制其产生不同的PWM占空比);
SRAM到外设(SRAM中预先保存的数据送入DAC产生各种波形);

四 DMA可以传递多少数据?

我理解在STM32中,它的概念被扩展了,也许更多的时候快速是其应用的重点,数据可以从1~65535个。
总之,每个DMA传送由3个操作组成:
1. 从外设数据寄存器或者从DMA_CMARx寄存器指定地址的存储器单元执行加载操作。
2. 存数据到外设数据寄存器或者存数据到DMA_CMARx寄存器指定地址的存储器单元。
3. 执行一次DMA_CNDTRx寄存器的递减操作。该寄存器包含未完成的操作数目。

仲裁器根据通道请求的优先级来启动外设/存储器的访问。
优先级分为两个等级:(可以在DMA传输过半、传输完成和传输错误时产生中断)
1.软件(4个等级:最高、高、中等、低);
2.硬件(有较低编号的通道比拥有较高编号的通道有较高的优先权);

DMA_DeInit(DMA1_Channel6);
//peripheral base address
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer;
//memory base address
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DST_Buffer;
//数据传输方向    Peripheral is source
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
//缓冲区大小 Number of data to be transferred (0 up to 65535).数据传输数目
DMA_InitStructure.DMA_BufferSize = BufferSize;
// the Peripheral address register is incremented
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
//the memory address register is incremented
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//the Peripheral data width
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
//the DMAy Channelx will be used in memory-to-memory transfer
//DMA通道的操作可以在没有外设请求的情况下进行,这种操作就是存储器到存储器模式。
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(DMA1_Channel6, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA1_Channel6, ENABLE);

五 外设的DMA请求映像

要使DMA与外设建立有效连接,这不是DMA自身的事情,是各个外设的事情,每个外设都有 一个
xxx_DMACmd(XXXx,Enable )函数,如果使DMA与ADC建立有效联系,就使用ADC_DMACmd

(ADC1,Enable); (这里我启用了ADC中的ADC1模块)。
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&AD_Value;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2; 
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);

DMA_Cmd(DMA1_Channel1, ENABLE);

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_Init(ADC1, &ADC_InitStructure);
//内部温度传感器  添加这一句
ADC_TempSensorVrefintCmd(ENABLE);
//################ Channel 10(电位器)
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);
//###### 内部温度传感器  Channel 16 ###################
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_55Cycles5);
//使能ADC1的DMA请求映像
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
//使用之前一定要校准
ADC_ResetCalibration(ADC1);
while (ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while (ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊唯0o

如果能够帮助到您,不介意的话,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值