My purpose is sampling signal by ADC channel with DMA data moving in STM32Fx board. Generate a square wave to ADC channel. If using DMA mode, some data is out of order or called mess. Same result happened on STM32F207 and STM32F373 board.
(1) When I collect converted data by using ADC EOC interrupt, the data array looks like a square wave. This is OK.
(2) I would like to try DMA circle instead of EOC IRQ, but the data array seems to mess up, some data missing or incorrect. It could worse if sampling rate was increasing. Below are my test results.
The picture shows my test result: EOC IRQ vs DMA circle mode
EOC IRQ vs DMA with sampling 62.5KHz The waveform in DMA became shorter.
The picture shows very worse DMA with sampling 200KHz The data on DMA mode mess up, but it's consistent by using ADC EOC IRQ.
enter code here
<<<< ADC config >>>>
/* ADC Common Init */
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_TwoSamplingDelay =
ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInit(&ADC_CommonInitStructure);
/* ADC1 DeInit */
ADC_StructInit(&ADC_InitStructure);
/* Configure the ADC1 in continuous mode */
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channels 6 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1,
ADC_SampleTime_480Cycles);
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
#ifdef __DMA_ENABLE__
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
/* Enable ADC1 DMA since ADC1 is the Master*/
ADC_DMACmd(ADC1, ENABLE);
#else
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
ADC_ITConfig(ADC1, ADC_IT_OVR, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
<<<< DMA config >>>>
/* DMA1 clock enable */
RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2, ENABLE );
/* DMA1 Channel1 Config */
DMA_DeInit(DMA2_Stream0);
DMA_DoubleBufferModeConfig(DMA2_Stream0, (uint32_t)ADCValB, DMA_Memory_1);
DMA_DoubleBufferModeCmd(DMA2_Stream0, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_0;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADCValA;
DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t) ADC1) + 0x4C;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = NUM_OF_ADC; // 512 buffer size
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_Medium;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream0, &DMA_InitStructure);
DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* DMA1 Channel1 enable */
DMA_Cmd(DMA2_Stream0, ENABLE);
Finally, I expect the result should be same as that using ADC EOC IRQ.