STM32_DMA 标准初始化设置解释

DMA 全称是:Direct Memory Access;根据 ST 公司提供的相关信息,DMA是STM32中一个独立于 Cortex-M3 内核的模块,有点类似于 ADC、PWM、TIMER 等模块;主要功能是起通信“桥梁”的作用,可以将所有外设映射的寄存器“连接”起来,这样就可以高速访问各寄存器,其传输不受 CPU 的支配,传输还是双向的;例如,从“表面”上看,它可以将 flash 中的数据与储存器中变量建立通讯,还可以将某一个外设的寄存器或缓冲器与另一个外设的寄存器或缓冲器建立双向通讯,有点像把外设硬件之间用“导线”连接在一起了。其间的通讯不占 CPU 资源,访问速度快,对于实时性强的应用将是一个很好的选择。下面代码是一个标准 DMA 设置,当然实际应用中可根据实际情况进行裁减:

//开启时钟,否则初始化无效。

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 

DMA_DeInit(DMA_Channel1);

上面这句是给 DMA 配置通道,根据 ST 提供的资料,STM3210Fx  DMA 包含个通道(CH1~CH7),也就是说可以为外设或 memory 提供“桥梁”;

 

DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

DMA_PeripheralBaseAddr 是 DMA_InitStructure 结构体中一个数据成员,给 DMA 一个起始地址,好比是一个 buffer 起始地址,ADC1_DR_Address 是我定义的一个地址变量;

 

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;

上面这句很显然是 DMA 要连接在 Memory 中变量的地址,ADC_ConvertedValue 是我自己在memory 中定义的一个变量地址;

 

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

上面的这句是设置 DMA 的传输方向,就如前面所说的,DMA 可以双向传输,也可以单向传输,这里设置的是单向传输,如果需要双向传输:把 DMA_DIR_PeripheralSRC 改成DMA_DIR_PeripheralDST 即可。

 

DMA_InitStructure.DMA_BufferSize = 2;

上面的这句是设置 DMA 在传输时缓冲区的长度,前面有定义过了 buffer 的起始地址:ADC1_DR_Address ,为了安全性和可靠性,一般需要给 buffer 定义一个储存片区,这个参数的单位有三种类型:Byte、HalfWord、word,我设置的 half-word(见下面的设置);32位的 MCU  half-word  16 bits。

 

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

上面的这句是设置 DMA 的外设递增模式,如果 DMA 选用的通道(CHx)有多个外设连接,需要使用外设递增模式:DMA_PeripheralInc_Enable;我的例子里 DMA 只与 ADC1 建立了联系,所以选用 DMA_PeripheralInc_Disable。

 

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

上面的这句是设置DMA的内存递增模式,DMA 访问多个内存参数时,需要使用DMA_MemoryInc_Enable,DMA只访问一个内存参数时可设置成 :DMA_MemoryInc_Disable。

 

DMA_InitStructure.DMA_PeripheralDataSize =

DMA_PeripheralDataSize_HalfWord;

上面的这句是设置 DMA 在访问时每次操作的数据长度。有三种数据长度类型,前面已经讲过了,这里不在叙述。

 

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

与上面雷同。在此不再说明。

 

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

上面的这句是设置 DMA 的传输模式:连续不断的循环模式,若只想访问一次后就不要访问了(或按指令操作来反问,也就是想要它访问的时候就访问,不要它访问的时候就停止),可以设置成通用模式:DMA_Mode_Normal。

 

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

上面的这句是设置 DMA 的优先级别:可以分为级:VeryHigh,High,Medium,Low.

 

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

上面的这句是设置 DMA  memory 中的变量互相访问的

 

DMA_Init(DMA_Channel1,&DMA_InitStructure);

前面那些都是对 DMA 结构体成员的设置,在次再统一对 DMA 整个模块做一次初始化,使得 DMA 各成员与上面的参数一致。

 

DMA_Cmd(DMA_Channel1,ENABLE);

使能启动。

 

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

 

 

 

 

  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是STM32F030 DMA初始化的代码示例: ```c /* 选择DMA通道 */ #define DMA_CHANNEL_ADC DMA1_Channel1 /* ADC DMA缓冲区大小 */ #define ADC_DMA_BUF_SIZE 16 uint16_t adc_dma_buf[ADC_DMA_BUF_SIZE]; // ADC DMA缓冲区 void dma_adc_init(void) { /* 使能DMA时钟 */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA配置 */ DMA_InitTypeDef dma_init; DMA_DeInit(DMA_CHANNEL_ADC); dma_init.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; // DMA外设地址为ADC数据寄存器地址 dma_init.DMA_MemoryBaseAddr = (uint32_t)adc_dma_buf; // DMA内存地址为ADC DMA缓冲区首地址 dma_init.DMA_DIR = DMA_DIR_PeripheralSRC; // DMA数据传输方向:外设到内存 dma_init.DMA_BufferSize = ADC_DMA_BUF_SIZE; // DMA缓冲区大小 dma_init.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不递增 dma_init.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增 dma_init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // 外设数据大小为半字(两个字节) dma_init.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // 内存数据大小为半字(两个字节) dma_init.DMA_Mode = DMA_Mode_Circular; // DMA循环模式 dma_init.DMA_Priority = DMA_Priority_High; // DMA优先级高 DMA_Init(DMA_CHANNEL_ADC, &dma_init); /* 使能DMA传输完成中断 */ DMA_ITConfig(DMA_CHANNEL_ADC, DMA_IT_TC, ENABLE); /* 使能DMA通道 */ DMA_Cmd(DMA_CHANNEL_ADC, ENABLE); } /* DMA传输完成中断处理函数 */ void DMA1_Channel1_IRQHandler(void) { if(DMA_GetITStatus(DMA1_FLAG_TC1)) { /* 在这里处理ADCDMA数据 */ DMA_ClearITPendingBit(DMA1_FLAG_TC1); } } ``` 在上面的代码中,先定义了DMA通道和ADC DMA缓冲区大小,并初始化ADC DMA缓冲区数组。然后在dma_adc_init函数中,首先使能了DMA时钟,之后设置DMA的配置参数,并调用DMA_Init函数进行初始化。此外,还使能了DMA传输完成中断,并打开DMA通道。 最后,在DMA传输完成中断处理函数中,我们可以对ADCDMA数据进行处理。通过上述步骤,DMA已经成功初始化,可以进行数据传输。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值