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);
DMA_BufferSize大小为多少,对应RAM即为多少
DMA的正常(Normal)模式:采集到DMA_BufferSize 的个数后,DMA停止。
DMA的循环模式:采集到DMA_BufferSize 的个数后,重新回到设置的RAM的起点位置,如此循环。
leebai_001你好
leebai_001谢谢你的回复!
如果采用DMA的循环模式,要把所有采集的数据都保存,不让数据覆盖,那怎么办?是不是要用中断重新设置DMA_MemoryBaseAddr ?
防止覆盖应该采用DMA正常模式,并使能DMA采集中断
采用DMA循环模式来采集的,不需要考虑数据覆盖,而是要进行多次采集求平均值,无须考虑数据是否发生了覆盖。
采用DMA正常模式采集的,DMA完成会产生标志,可以用软件查询也可用中断,将数据处理完后,可再次启动DMA。
以上只是一家之言,可参考一下。
leebai_001你好,你能告诉我QQ吗?我的184368205
采用DMA循环模式来采集的,不需要考虑数据覆盖,而是要进行多次采集求平均值,无须考虑数据是否发生了覆盖。
我刚试了下,如果AD采用 连续 扫描采样的话,时刻都在采样。
DMA采用循环模式的话,那时刻都在转移数据到RAM ,数据时刻被覆盖更新
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)
{
.....//采样数据处理
}
谢谢各位
通过各位的指导和自己实验
这个问题我已经弄懂了
谢谢!
以后有什么问题
可以来这个群来交流 26260068