cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F100R8 reading Multichannel ADC with Scan Mode

metin
Associate II
Posted on April 25, 2014 at 22:55

Dear friends,

I need an help about multichannel ADC reading with scan mode.

When I configure ADC, unfortunately interrupt routine can occure only one time.

And I can not read the other channels.Do you think what is the problem? Why can not I use Scan mode?

Best wishes.

Öztürk, Metin.

 RCC_ADCCLKConfig(RCC_PCLK2_Div2);

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_6 | GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

 ADC_InitTypeDef ADC_InitStructure;

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 11;

  ADC_Init(ADC1, &ADC_InitStructure);

 ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

  NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

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_15, 11, ADC_SampleTime_55Cycles5);

   ADC_Cmd(ADC1, ENABLE); 

   ADC_ResetCalibration(ADC1);

  while(ADC_GetResetCalibrationStatus(ADC1));

   ADC_StartCalibration(ADC1);

   while(ADC_GetCalibrationStatus(ADC1));

   ADC_SoftwareStartConvCmd(ADC1, ENABLE);
6 REPLIES 6
Posted on April 25, 2014 at 23:33

The prescribed method is to use DMA, not the EOC interrupt.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
metin
Associate II
Posted on May 26, 2014 at 11:33

Dear friend,

Thank you very much for your supports.

Is it meaning that if we want to use scan mode, do we have to use DMA?

best wishes.

Ozturk, Metin.

Posted on May 26, 2014 at 21:32

Yes, use DMA, and the use the HT (double size buffer) or TC interrupt from the DMA to act as a group EOC for your collection of samples. Use circular mode, and if you have a desired periodicity trigger the ADC with a TIM channel to start sampling the group.

The reason not to do it with ADC EOC interrupts is the rate at which they will occur is too high to be practical. I'm not even sure ST supports it, as I've never seen a reason to try, but we do occasionally see people wanting to try.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
metin
Associate II
Posted on May 27, 2014 at 16:40

Dear friend,

Thank you very much for your kind replay.

Yes I can read in scan mode with DMA.(I can check the ADC datas in debug mode)

At this point what is the best way to evaluate channel values?

1- In my opinion, when the DMA interrupt occurs, I have to stop DMA interrupt and DMA function. And read the datas.

  

ADC_DMACmd(ADC1, DISABLE);               

  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, DISABLE); 

2- And after an internal or external event, I can start DMA again.

  ADC_DMACmd(ADC1, ENABLE);

  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);

But when I do this, data' s order change. What do I have to do?

best wishes.

void DMA1_Channel1_IRQHandler(void){  

 DMA_ClearITPendingBit(DMA1_IT_TC1);

  

  ADC_DMACmd(ADC1, DISABLE);               

  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, DISABLE);    

}

 

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

void EXTI0_IRQHandler(void){    

 if(EXTI_GetITStatus(EXTI_Line0) != RESET){

  EXTI->PR = EXTI_Line0;     //EXTI_ClearITPendingBit(EXTI_Line4);

  

  ADC_DMACmd(ADC1, ENABLE);

  DMA_ITConfig(DMA1_Channel1, DMA1_IT_TC1, ENABLE);

 

  }

}

Posted on May 27, 2014 at 17:46

You can make the ADC trigger off EXTI11

You can do a software trigger

You can copy the values in the DMA TC interrupt

You can double the buffer size, and process the first half at DMA HT, and the second half at DMA TC

If I had to use EXTI0, then I'd set the ADC in Scan:ENABLE, Continuous:DISABLE, DMA to circular, pointing at my buffer, and enable it ONCE. In the EXTI0 interrupt I would trigger a ''start conversion'', and process the data in the DMA TC interrupt.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
metin
Associate II
Posted on May 29, 2014 at 07:34

Dear friend,

In discontinuous and scan mode I triggered start conversion in EXTI0.

And I can read datas properly.

Thank a lot.

with my best wishes

Ozturk, Metin.