打印

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

[复制链接]
9649|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
thxcumt|  楼主 | 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);  

 

沙发
leebai_001| | 2007-12-13 14:30 | 只看该作者

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

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

使用特权

评论回复
板凳
thxcumt|  楼主 | 2007-12-13 15:14 | 只看该作者

leebai_001你好

   leebai_001谢谢你的回复!

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

使用特权

评论回复
地板
leebai_001| | 2007-12-13 15:37 | 只看该作者

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

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

使用特权

评论回复
5
mojingxian| | 2007-12-14 11:38 | 只看该作者

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)
{
   .....//采样数据处理
}

使用特权

评论回复
6
么么沫沫| | 2014-1-13 14:18 | 只看该作者
thxcumt 发表于 2007-12-14 18:36
通过各位的指导和自己实验这个问题我已经弄懂了谢谢!以后有什么问题可以来这个群来交流  262600 ...

你好,为什么群设置成不允许人进入呢、?》

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

27

帖子

1

粉丝