2014-02-25 02:44 AM
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
2014-02-25 06:36 AM
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, Hal2014-02-25 06:55 AM
I think I'm missing out something simple or doing something stupid.
You're posting incomplete code for an unspecified platform, does that count.2014-02-25 07:48 AM
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,/rygelxvi2014-02-25 08:43 AM
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
]2014-02-26 02:58 AM
Hi,
In that case, you will also need to activate the clock for the ADC1 peripheral.RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_ADC1
,
ENABLE
);
Regards,rygelxvi