cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 ADC_TripleMode_RegSimult

yayi
Associate II
Posted on December 20, 2012 at 17:27

Hi,

I am trying to use the 3 ADC in simultaneous mode.

I receive correctly every data but I am not able to catch any interruption in order to drive data on the good place. When I have my table I want to dispatch adc_channel_1to a table, adc_channel_2 to a other table etc...

But I have no interruption.

Here is my code to init DMA:

void DMA_Config(void)

{

 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

 

  /* DMA2 Stream0 channel0-11-12 configuration **************************************/

  DMA_InitStructure.DMA_Channel = DMA_Channel_0; 

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;

  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCTripleConvertedDemiVal;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

  DMA_InitStructure.DMA_BufferSize = 180;

  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_High;

  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;        

  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);

 

 /**  Test de l'interruption sur la fin du transfert **/

 DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_TE, ENABLE);

  /* DMA2_Stream0 enable */

  DMA_Cmd(DMA2_Stream0, ENABLE);

} My code to init GPIO:

void ADC_Gpio_Config(void)

{

  /* Enable peripheral clocks */

  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);

  

 /* Configure ADC Channel 0 - 3 - 4 - 5 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 /* Configure ADC Channel 6 - 8 - 9 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 /* Configure ADC Channel 10 - 12 - 13 pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12 | GPIO_Pin_13;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

}

And my code to init ADC:

void ADC_Config(void)

{

 ADC_Gpio_Config();

 DMA_Config();

 

 /* Enable peripheral clocks */

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |

                         RCC_APB2Periph_ADC3, ENABLE);

 

/*******************************************************************************/

/*  ADCs configuration: triple simultaneous with 10cycles delay   */

/*******************************************************************************/ 

 /* ADC Common Init */

  ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult ;

  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;

  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1;

  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles;

  ADC_CommonInit(&ADC_CommonInitStructure);

/**< ADC1 regular channels 0 and 3 and 4 (and 5) configuration */

 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = 3;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channels 0 and 3 and 4 (and 5) configuration */

  ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_3Cycles);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 2, ADC_SampleTime_3Cycles);

 ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 3, ADC_SampleTime_3Cycles);

// ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 4, ADC_SampleTime_15Cycles);

 

/**< ADC2 regular channels 6 and 8 and 9 configuration */

  ADC_Init(ADC2, &ADC_InitStructure);

  /* ADC2 regular channels 6 and 8 and 9 configuration */

  ADC_RegularChannelConfig(ADC2, ADC_Channel_6, 1, ADC_SampleTime_3Cycles);

  ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 2, ADC_SampleTime_3Cycles);

 ADC_RegularChannelConfig(ADC2, ADC_Channel_9, 3, ADC_SampleTime_3Cycles);

 

/**< ADC3 regular channels 10, 12 and 13 configuration */

  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channels 10, 12 and 13 configuration */

  ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_3Cycles);

  ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 2, ADC_SampleTime_3Cycles);

 ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 3, ADC_SampleTime_3Cycles);

 

 /* Enable EOC Interrupt */

 ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

 

 /* Enable DMA request after last transfer (Multi-ADC mode)  */

  ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE);

 

 /* Enable ADC1 & ADC2 & ADC3 */

  ADC_Cmd(ADC1, ENABLE);

 ADC_Cmd(ADC2, ENABLE);

 ADC_Cmd(ADC3, ENABLE);

} And my handler:

void ADC1_IRQHandler(void)

{

 cptADCIt++;

}

void DMA2_Stream0_IRQHandler(void)

{

 DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0 | DMA_IT_TEIF0);

 cptDMAIt++;

}

The cptXXXIt never increase...

Can someone help me?

Thanks.

18 REPLIES 18
raptorhal2
Lead
Posted on December 20, 2012 at 18:26

You are not getting correct values for ADC 2 and 3. The correct pin assignments are:

ADC2 CH8 is PB0

ADC2 CH9 is PB1

ADC3 CH10 is PC0

ADC3 CH12 is PC2

ADC3 CH13 is PC3

This isn't the cause of missing interrupts. I will take a look and see if I can find that problem.

Cheers, Hal

raptorhal2
Lead
Posted on December 20, 2012 at 18:38

You are missing the command to connect ADC1 to DMA

  /* Enable ADC1 DMA since ADC1 is the Master*/

  ADC_DMACmd(ADC1, ENABLE);

and to start conversion

  /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConv(ADC1);

Cheers, Hal

yayi
Associate II
Posted on December 20, 2012 at 19:12

Hello,

I do this in my main, that I have not copy...

But for the channel I will take a look, I have some difficulties to understand the pin assignment explication on data sheet. Thanks for the informations.

Jérome

zzdz2
Associate II
Posted on December 20, 2012 at 19:57

I'm not familiar with F4 but in my F1 I had to enable NVIC:

NVIC_EnableIRQ(DMA1_Channel1_IRQn);

raptorhal2
Lead
Posted on December 20, 2012 at 20:20

Perhaps this will help understanding:

PC0 assigned to ADC123_IN10 means that pin PC0 is available as channel 10 on all three ADCs.

PA4 assigned to ADC12_IN4 means that pin PA4 is available as channel 4 on ADC1 and 2.

If you had a 144 pin count or higher F4, PF3 for example is available only as ADC3 channel 9. Note that there is no channel 9 on ADC123.

Cheers, Hal

yayi
Associate II
Posted on December 21, 2012 at 08:08

Hello,

This is part of my main :

   NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn | DMA2_Stream0_IRQn;

   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 

   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

   NVIC_Init(&NVIC_InitStructure);

 ADC_Config();    //Which is shown is firt message.

 

 while (!DMA_GetCmdStatus(DMA2_Stream0))

 {

  i++;

 }

 /* Start ADC1 Software Conversion */

  ADC_SoftwareStartConv(ADC1); After that I enter in my infinite loop.

I check my project on microXplorer and you are right a do mistake on pin assignment!!! I correct that thx..
yayi
Associate II
Posted on December 21, 2012 at 09:27

Just for who need it, here is the correction of the pin assignment in accordance with microXplorer for a STM32F407VG.

void ADC_Gpio_Config(void)

{

  /* Enable peripheral clocks */

  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);

  

 /* Configure ADC Channel 0 - 3 - 4 - 5 - 6, GPIOA pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 /* Configure ADC Channel 8 - 9, GPIOB pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 /* Configure ADC Channel 10 - 12 - 13, GPIOC pin as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3;

  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

}
zzdz2
Associate II
Posted on December 21, 2012 at 09:52

Have you tried to clear the adc flag in adc handler like you do in dma handler?

Does it work when you disable adc irq?

yayi
Associate II
Posted on December 21, 2012 at 09:58

Hello knik,

Yes I do but as I never detect the interruption nothing update.

void ADC1_IRQHandler(void)

{

 if ( ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) )

 {

  ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

 }

 cptADCIt++;

}

But I detect the flag (and reset it) in infinite loop and it increase correctly my cpt...

On the other side, I am not sure to use the good handler.

Jerome