stm32103xx请教DMA(DMA_Mode)使用问题!

yaschiro   2007-12-13 10:33 楼主
stm32手册上这样描述:

循环模式:
循环模式用于处理循环缓冲区和连续的数据传输(如ADC的扫描模式)。在DMA_CCRx寄存器中的CIRC位用于开启这一功能。当启动了循环模式,数据传输的数目变为0时,将会自动地被恢复成配置通道时设置的初值,DMA操作将会继续进行。

我刚编了个AD采样: 软件启动8 通道连续 扫描采样,用DMA传输数据到RAM区 AD与DMA的初始化代码如下:

问题是:当DMA_InitStructure.DMA_BufferSize = 8,时候
 DMA_InitStructure.DMA_Mode =DMA_Mode_Normal;   或者= Circular

RAM存储区始终只有显示8个数据,不是说DMA_Mode为 Circular时候数据传输数目会自动加载吗?为什么改变DMA_Mode 对结果没有影响?  请问一下大家,刚开始学习arm,见笑了!!!

 /* DMA Channel1 Configuration ---------------------------------*/
  DMA_DeInit(DMA_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADC_ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 8;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
  DMA_InitStructure.DMA_Mode =DMA_Mode_Circular;    // Normal
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(DMA_Channel1, &DMA_InitStructure);
  
  /* Enable DMA Channel1 */
  DMA_Cmd(DMA_Channel1, ENABLE);  
    
  /* ADCx Configuration (ADC1CLK = 14 MHz) ------------------------*/
  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 = 8;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADCx Regular Channel Configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_55Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_55Cycles5);
  

  /* Enable ADCx's DMA interface */
  ADC_DMACmd(ADC1, ENABLE);
  
  /* Enable ADCx */
  ADC_Cmd(ADC1, ENABLE);
   
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  

 

回复评论 (6)

DMA_BufferSize大小为多少,对应RAM即为多少

DMA的正常(Normal)模式:采集到DMA_BufferSize 的个数后,DMA停止。
DMA的循环模式:采集到DMA_BufferSize 的个数后,重新回到设置的RAM的起点位置,如此循环。
点赞  2007-12-13 14:30

leebai_001你好

   leebai_001谢谢你的回复!

   如果采用DMA的循环模式,要把所有采集的数据都保存,不让数据覆盖,那怎么办?是不是要用中断重新设置DMA_MemoryBaseAddr ?
点赞  2007-12-13 15:14

防止覆盖应该采用DMA正常模式,并使能DMA采集中断

采用DMA循环模式来采集的,不需要考虑数据覆盖,而是要进行多次采集求平均值,无须考虑数据是否发生了覆盖。
采用DMA正常模式采集的,DMA完成会产生标志,可以用软件查询也可用中断,将数据处理完后,可再次启动DMA。
以上只是一家之言,可参考一下。
点赞  2007-12-13 15:37

leebai_001你好,你能告诉我QQ吗?我的184368205

 
采用DMA循环模式来采集的,不需要考虑数据覆盖,而是要进行多次采集求平均值,无须考虑数据是否发生了覆盖。 



我刚试了下,如果AD采用 连续 扫描采样的话,时刻都在采样。

DMA采用循环模式的话,那时刻都在转移数据到RAM ,数据时刻被覆盖更新

点赞  2007-12-13 17:02

DMA的循环模式不覆盖数据

如果采用DMA的循环模式,要把所有采集的数据都保存,不让数据覆盖,那怎么办?

可以开辟一个足够大的内存空间。假设采样128次之后对数据进行处理,则定义:
u16 ADC_ConvertedValue[8 x 128];

DMA_InitStructure.DMA_BufferSize = 8 x 128;

DMA_ITConfig(DMA_Channel1, DMA_IT_TC, ENABLE); //DMA传输完8x128个数据之后产生一个TC中断。

void DMAChannel1_IRQHandler(void)
{
   .....//采样数据处理
}

点赞  2007-12-14 11:38

谢谢各位

通过各位的指导和自己实验
这个问题我已经弄懂了

谢谢!
以后有什么问题
可以来这个群来交流  26260068
点赞  2007-12-14 18:36
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复