cancel
Showing results for 
Search instead for 
Did you mean: 

Triggering 3ADC's simultaneously in continuous mode by a timer.

Sgowd.1
Associate II

I have 3 ADCs (ADC1, ADC2, ADC3) configured with 3 different channels for 3 gpio pins to collect the data and all 3 ADC's are triggered simultaneously by TIM1 at the rising edge of the pulse.

It is also configured in the single conversion mode (i.e., at the rising edge of the pulse ADC's are triggered and conversions are made and it is stopped), it is working all good till here. but, when the continuous mode is enabled the ADC values are still triggered but the values getting is completley different (to be precise these values doesnot make any sense and kind of some random junk value).

so my question is, is it possible to configure ADC is continuous conversion mode and also trigger all the 3 ADC's simultaneously at the rising edge of pulse and collect the values after disabling the ADC's at some point?

// ADC's channel and gpio pin initializations. 
 
 
   cADCReadout::sADCInitStruct adc1;
 
         adc1.ADCChannel = ADC1;
 
         adc1.DMAChannel = DMA_Channel_0;
 
         adc1.DMAStream = DMA2_Stream0;                                
 
         adc1.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
 
 
         cADCReadout::sADCInitStruct adc2;
 
         adc2.ADCChannel = ADC2;
 
         adc2.DMAChannel = DMA_Channel_1;
 
         adc2.DMAStream = DMA2_Stream3;
 
         adc2.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
 
 
         cADCReadout::sADCInitStruct adc3;
 
         adc3.ADCChannel = ADC3;
 
         adc3.DMAChannel = DMA_Channel_2;
 
         adc3.DMAStream = DMA2_Stream1;
 
         adc3.DMATRSFCompleteFlag = DMA_FLAG_TEIF0;
 
 
         m_oADC1.initialize(adc1);
 
         m_oADC1.addChannel(GPIOA, GPIO_Pin_1,ADC_Channel_1,ADC_SampleTime_112Cycles);
 
 
         m_oADC1.initialize(adc2);
 
         m_oADC1.addChannel(GPIOA, GPIO_Pin_2,ADC_Channel_2,ADC_SampleTime_112Cycles);
 
 
         m_oADC1.initialize(adc3);
 
         m_oADC1.addChannel(GPIOA, GPIO_Pin_3,ADC_Channel_3,ADC_SampleTime_112Cycles);
 
 
//ADC and DMA configuartions
 
void cADCReadout::initialize(sADCInitStruct init)
 
{
 
   m_sInitStruct = init;
 
 
   ADC_InitTypeDef      ADC_InitStructure;
 
   ADC_CommonInitTypeDef ADC_CommonInitStructure;
 
   DMA_InitTypeDef      DMA_InitStructure;
 
 
   //DMA
 
   DMA_InitStructure.DMA_Channel = init.DMAChannel;
 
   DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(init.ADCChannel->DR);
 
   DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&m_aRecBuffer);
 
   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
 
   DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;                              //It was 0 before
 
   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_Word;
 
   DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
 
   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
 
   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(init.DMAStream, &DMA_InitStructure);
 
   DMA_Cmd(init.DMAStream, ENABLE);
 
 
   //ADC
 
   ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;
 
   ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
 
   ADC_CommonInitStructure.ADC_DMAAccessMode =ADC_DMAAccessMode_1;
 
   ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
 
   ADC_CommonInit(&ADC_CommonInitStructure);
 
 
   ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
 
   ADC_InitStructure.ADC_ScanConvMode = ENABLE;                          
 
   ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                         
 
   ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising ;      
 
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;            
 
   ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 
   ADC_InitStructure.ADC_NbrOfConversion =1;
 
   ADC_Init(init.ADCChannel, &ADC_InitStructure);
 
 
   ADC_EOCOnEachRegularChannelCmd(init.ADCChannel, DISABLE);
 
 
   /* Enable DMA request after last transfer (Single-ADC mode) */
 
   ADC_DMARequestAfterLastTransferCmd(init.ADCChannel, ENABLE);
 
}

10 REPLIES 10
Javier1
Principal

what chip are you using?

Are you using cubeMX?

The most common error here is trying to read 32bits from a 16bit register of the ADC (type casting error)

>so my question is, is it possible to configure ADC is continuous conversion mode and also trigger all the 3 ADC's simultaneously at the rising edge of pulse and collect the values after disabling the ADC's at some point?

 Yes, you could "collect the values" inside a End of conversion event "manually" or configure a DMA channel to do it for you.

we dont need to firmware by ourselves, lets talk
Sgowd.1
Associate II

I am using STM32F4 chip.

No, i am not using cubeMX.

https://www.youtube.com/watch?v=8lmujnLuJrQ maybe this is helpful for you

we dont need to firmware by ourselves, lets talk

I read the below statement in some forum, can you please confirm if it is right??

`` if you want ADC conversions to be started each time on specific trigger event you should not use continuous mode. In other words, change:''

  hadc1.Init.ContinuousConvMode = ENABLE;

to

  hadc1.Init.ContinuousConvMode = DISABLE;
 
 

I am basically triggering the ADC by timer whenever there is a rising edge in the pulse, so in this case if i configure it in a continupus mode will it work?(i mean in contnious mode do the contious conversion happen).

>I read the below statement in some forum, can you please confirm if it is right??

yes its right

>if i configure it in a continupus mode will it work?(i mean in contnious mode do the contious conversion happen).

it should work but you wont have any control about when the ADCs conversions are happening, and your DMA will be busy as hell.

Can you show me in your main how do you initialice DMA?

I just happen to know today there is a bug in CUBEMX and MX_DMA_Init should be on top of the initialization functions

0693W00000GWS5bQAH.png 

we dont need to firmware by ourselves, lets talk

>it should work but you wont have any control about when the ADCs are happening, and your DMA will be busy as hell.

if this is the case and if '' if you want ADC conversions to be started each time on specific trigger event you should not use continuous mode.'' this statement is also true then if i configure it in a continuous mode how will i be able to get continuous data?? Because in my code ADC is triggerd at the rising edge of the pulse by the timer.

Also, when i enable the continuous mode and when i check the DMA buffer i could see only one value.

   ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising ;      
 
   ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;            

Yes, DMA is on top of ADC.

0693W00000GWUZTQA5.png

>how will i be able to get continuous data?? Because in my code ADC is triggerd at the rising edge of the pulse by the timer.

Good question, i would expect the adc to start with the timer and continue automatically from there.(i have never tried this, its important for my DSP calculations the time between ADC measurements)

>Yes, DMA is on top of ADC.

ok, if you say so.

What hapened to me today is the ADC init function was trying to configure the DMA but nothing was happening becasue the DMA clock was not yet enabled.

we dont need to firmware by ourselves, lets talk

>i wouls expect the adc to start with the timer and continue automatically from there.

but its not happening. ADC is started at the rising edge but i could see only one data in the buffer even though it is in continuous mode. I believe it is because it is external triggered by the timer at the rising edge. I am stuck in this from past 2-3 days, but cannot conclude if this is the exact reason, if yes then i can continue with other project without wasting much time on this.

I saw your link, are you using only one ADC or you have ADC2 and ADC3 also enabled??

> I saw your link, are you using only one ADC or you have ADC2 and ADC3 also enabled??

im using ADC1 and ADC3 (20 channels simultaneous)

>I am stuck in this from past 2-3 days, but cannot conclude if this is the exact reason, if yes then i can continue with other project without wasting much time on this.

Did you tried following with cubeMX only? maybe youre missing something

we dont need to firmware by ourselves, lets talk