cancel
Showing results for 
Search instead for 
Did you mean: 

ADC help needed

jonfs2000
Associate II
Posted on February 25, 2014 at 11:44

Hi,

I think I'm missing out something simple or doing something stupid. I'm trying to do adc conversion on 3 channels on ADC1 continuously (loop). I use EOC interrupt and store the adc value in buffer. But only first conversion is done on power up. Thanks John

// *** Restore ADC registers to default values *** 
ADC_DeInit(); 
// *** ADC INTERRUPT config -- Interrupt on EOC - End of Conversion*** 
ADC_ITConfig (ADC1, ADC_IT_EOC, ENABLE ); 
// *** ADC COMMON *** 
ADC_cmnStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; 
ADC_cmnStruct.ADC_Mode = ADC_Mode_Independent; 
ADC_cmnStruct.ADC_Prescaler = ADC_Prescaler_Div8; 
ADC_cmnStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_19Cycles; 
ADC_CommonInit(&ADC_cmnStruct); 
// *** Assign values to structure *** 
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; 
// Continuous conversion 
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; 
ADC_InitStruct.ADC_ExternalTrigConv = 0; 
// NO DEFINITION IS AVALIABLE FOR THIS?? 
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; 
ADC_InitStruct.ADC_NbrOfConversion = 3; 
ADC_InitStruct.ADC_Resolution = ADC_Resolution_8b; 
ADC_InitStruct.ADC_ScanConvMode = ENABLE; 
// Multi Channel 
ADC_Init(ADC1, &ADC_InitStruct); 
// ***Regular channel config*** 
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_28Cycles); 
// Chn0, 1st pos 
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_28Cycles); 
// Chn1, 2nd pos 
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_28Cycles); 
// Chn2, 3rd pos 
// *** ENABLE EOC - End OF Conversion bit after each conversion *** 
ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE); 
// *** Enable ADC1 *** 
ADC_Cmd(ADC1, ENABLE); 
// *** START Conversion *** 
ADC_SoftwareStartConv (ADC1); 
/*---------------------------------*/
/*-------- INTERRUPT --------------*/
/*---------------------------------*/
void
ADC_IRQHandler() 
{ 
/*----- CHECK for End Of Conversion - ADC -------------*/
if
( (ADC1->SR & ADC_SR_EOC ) == ADC_SR_EOC) 
{ 
GPIOD->BSRRL = ORANGE_LED; 
// DEBUG led (for oscilloscope) 
gb_nADC_Val[m_cADC_Chn_Idx++] = ADC1->DR; 
// Store the value in buffer, EOC flag cleared on read
ADC1->SR &= ~ADC_SR_EOC; 
// Clear the flag 
// ADC1->CR2 |= ADC_CR2_SWSTART; // I believe this is not needed on CONTINUOUS mode 
} 
GPIOD->BSRRH = ORANGE_LED; 
// DEBUG led (for oscilloscope) 
}

#adc-scan-continuous
5 REPLIES 5
raptorhal2
Lead
Posted on February 25, 2014 at 15:36

The recommended method for more than one channel is to use DMA to make sure that all the samples are recorded, and save each set of three values when the DMA counter goes to zero.

The conversion is circular, but the storage pointer is incremented ad infinitum.

Cheers, Hal

Posted on February 25, 2014 at 15:55

I think I'm missing out something simple or doing something stupid.

You're posting incomplete code for an unspecified platform, does that count.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
troy1818
Senior
Posted on February 25, 2014 at 16:48

I am interested in these kinds of use case. But as Clive suggested, please disclose all relevant code in order for us to help.

Regards,

/rygelxvi
jonfs2000
Associate II
Posted on February 25, 2014 at 17:43

Thank you all for the suggestion,

Sorry I thought I mentioned it before

microcontroller - STM32F407

IDE - CooCox

There is nothing much in the code, I'm just reading the buffer and sending on UART. I am not doing any modification to the ADC or interrupt.

I am expecting the interrupt to happen more than once, but I can see it enters the interrupt routine (probe the led ) on reset and thats it. Only one conversion is done. I get back correct reading as well on uart.

 

 

[of course I am resetting the index variable

m_cADC_Chn_Idx inside the interrupt once maximum is reached

]

troy1818
Senior
Posted on February 26, 2014 at 11:58

Hi,

In that case, you will also need to activate the clock for the ADC1 peripheral.

RCC_APB2PeriphClockCmd

(

RCC_APB2Periph_ADC1

,

ENABLE

);

Regards,

rygelxvi