cancel
Showing results for 
Search instead for 
Did you mean: 

Problem in using DMA for ADC Fast Interleaved mode in STM32F103VET

abbas
Associate II
Posted on April 28, 2013 at 09:27

I configured ADC1 and ADC2 on fast interleaved mode and use DMA for ADC data transfer. I expect that when I call the StartConversion function of ADC1, the ADC2 should be started automatically by ADC1 after 7 ADC clock cycle and inversely ADC2 restart ADC1 continuously .

but when I start ADC1, ADC2 does not work. for bypassing this problem, I manually started both ADCs. in this situation, both ADCs work but the DMA output is not continuous i.e. in regular time intervals, it seems that the ADCs values is not transferred by DMA. I found it because I had known the input signal in my experiment.

I couldn�t find any example for this use in STM32F10x in ST site or STD_PERIPH examples or internet. I urgently need to know what the problem is.

Please help me if you have passed this issue or know what the wrong is

thanks

my code in main() is

ADC_SoftwareStartConvCmd(ADC1, ENABLE); // start the process

while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));

DMA_ClearFlag ( DMA1_FLAG_TC1 ) ;

the config of ADC is as below

 ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;

 ADC_InitStructure.ADC_ScanConvMode = DISABLE;

 ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

 ADC_InitStructure.ADC_NbrOfChannel = 1;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   

 ADC_DeInit(ADC1);    ADC_Init(ADC1, &ADC_InitStructure);

 ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 1, ADC_SampleTime_1Cycles5);  

ADC_DMACmd(ADC1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);   

ADC_DeInit(ADC2);

ADC_Init(ADC2, &ADC_InitStructure);

ADC_RegularChannelConfig(ADC2, ADC_Channel_15, 1, ADC_SampleTime_1Cycles5);  ADC_Cmd(ADC1, ENABLE);

ADC_Cmd(ADC2, ENABLE);

and the config of DMA is

 

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* Enable DMA clock */

 

DMA_Cmd(DMA1_Channel1, DISABLE);

             

 

DMA_DeInit(DMA1_Channel1);

 

DMA_InitStructure->DMA_PeripheralBaseAddr = (uint32_t) ADC1_DR_Address;

 

DMA_InitStructure->DMA_MemoryBaseAddr = (uint32_t) data_buffer;

 

DMA_InitStructure->DMA_DIR = DMA_DIR_PeripheralSRC;

 

DMA_InitStructure->DMA_BufferSize = BuffSIZE;

 

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;

 

DMA_InitStructure->DMA_Priority = DMA_Priority_VeryHigh;

 

DMA_InitStructure->DMA_M2M = DMA_M2M_Disable;

 

DMA_Init(DMA1_Channel1, DMA_InitStructure);

 

DMA_Cmd(DMA1_Channel1, ENABLE);

              

#stm32f103
7 REPLIES 7
Posted on April 28, 2013 at 15:00

  /* Enable ADC2 external trigger conversion */

  ADC_ExternalTrigConvCmd(ADC2, ENABLE);

Per STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\ADC\RegSimul_DualMode (a close equivalent)

I'd be tempted to order the APB clock and initialization differently than you. Also make sure to do the calibration step.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zzdz2
Associate II
Posted on April 28, 2013 at 17:22

I think it's just buggy, I tried different trigger configuration and no go -- only one ADC is started.

I ended up starting both ADCs with a precise CPU delay and then everything is OK.

You need an accurate delay, one CPU cycle precision: ADC2->delay->ADC1

abbas
Associate II
abbas
Associate II
Posted on April 28, 2013 at 23:05

knik, look my code, it works. you may had a similar mistake like me. thank you for review anyway

good luck

zzdz2
Associate II
Posted on April 29, 2013 at 15:00

Thanks, I finally set those triggers correctly and now it starts as expected.

But I don't have any DMA issues, it all works like a charm.

zzdz2
Associate II
Posted on April 29, 2013 at 22:16

when I use DMA for loading the data_buffer, the ADC samples seems to be partially for different portions of the analog signal. this portions have constant length (e.g. 4*2 samples) and the interruptions occurred  between two parts seems to be fixed.

 

I suspect that the problem may be related to the DMA running in circular mode.

It this mode after filling the buffer DMA is restarted and the buffer is continuously filled with new data.

When you print it, new data are interleaved with old data as DMA transfers aren't stopped.

You can try it without circ mode.

abbas
Associate II
Posted on April 30, 2013 at 09:16

Thank you so much knik!

you were right!  I should have stop ADC immediately after DMA transfer completion...

what a good place ST forum is! 🙂