AnsweredAssumed Answered

Configuring ADC to sample group of channels

Question asked by BeginEnd on Nov 18, 2013
Latest reply on Nov 18, 2013 by Clive One
I am fighting with this from couple of days. My uC is STM32F407VG.
I want to sample 3 triggered channels. For now I am triggering ADC using software but finaly I will use timer and dma, but for now I can't figure out how to configure ADC to do exactly 3 conversions and fire interrupt after each conversion. Could someone point me out what I am doing wrong in this sample code?
#include "arch/stm32f4xx/stm32f4xx.h"
static volatile int g_adc_cnt;
static uint32_t adc_data[ 3 ];
 
void ADC_IRQHandler( void )
{
    uint32_t status = READ_REG( ADC2->SR );
    if( status & ADC_SR_EOC )
        adc_data[ g_adc_cnt++ ] = READ_REG( ADC2->DR );
}
 
int main( void )
{
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
 
    ADC_CommonInitTypeDef adc_cmn;
    adc_cmn.ADC_Mode = ADC_Mode_Independent;
    adc_cmn.ADC_Prescaler = ADC_Prescaler_Div2; // 16MHz / 2 = 8MHz
    adc_cmn.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    adc_cmn.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_20Cycles;
 
    ADC_CommonInit(&adc_cmn);
 
    ADC_InitTypeDef adc2_conf;
    adc2_conf.ADC_Resolution = ADC_Resolution_12b;
    adc2_conf.ADC_ScanConvMode = ENABLE;
    adc2_conf.ADC_ContinuousConvMode = DISABLE;
    adc2_conf.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    adc2_conf.ADC_ExternalTrigConv = 0;
    adc2_conf.ADC_DataAlign = ADC_DataAlign_Right;
    adc2_conf.ADC_NbrOfConversion = 3;
 
    ADC_Init(ADC2, &adc2_conf);
    ADC_DiscModeChannelCountConfig(ADC2, 3);
    ADC_DiscModeCmd(ADC2, ENABLE);
    ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE);
 
    ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_13, 2, ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 3, ADC_SampleTime_480Cycles);
    ADC_Cmd(ADC2, ENABLE);
 
    NVIC_InitTypeDef nvic;
    nvic.NVIC_IRQChannel = ADC_IRQn;
    nvic.NVIC_IRQChannelPreemptionPriority = 3;
    nvic.NVIC_IRQChannelSubPriority = 0;
    nvic.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic);
 
    while( 1 )
    {
        ADC_SoftwareStartConv(ADC2);
        do { ; } while( g_adc_cnt < 3 );
        __NOP(); // Never gets here
        g_adc_cnt = 0;
    }
 
    return 0;
}

Outcomes