AnsweredAssumed Answered

ADC: How to read 6 signals?

Question asked by s.alex on Nov 25, 2011
Latest reply on Dec 5, 2011 by s.alex
Hi. This is the first time I write in this forum.
I must read 6 analog signals, 3 from an acelerometer and 3 from a gyroscope, every 20 ms. I am using PC1-PC3 and PA1-PA3 (STM32 Discovery VL), so this is my configuration code, programmed with Atollic True Studio (sorry for the extension):

void Configura_ADC(void)
{
    ADC_InitTypeDef ADC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    // Se configuran los pines PA1 - PA3 y PC1 - PC3 como entradas ****ógicas
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    // Reloj para el ADC (max 14MHz --> 72/6=12MHz)
    RCC_ADCCLKConfig (RCC_PCLK2_Div6);
    // Habilita el sistema de reloj del ADC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

    // Configura el ADC
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_InitStructure.ADC_ScanConvMode = ENABLE;                            // Conversión de múltiples canales
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;                        // Modo de conversión contínua
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;        // Sin fuente de disparo para la conversión
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;                    // Alineación de los datos izquierda
    ADC_InitStructure.ADC_NbrOfChannel = 6;                                    // 6 canales de conversión (Ax, Ay, Az, Gr, Gp, Gy)

    // Se asigna el canal y el orden de conversión
    ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5);        // PA1 = ADC1_IN1
    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5);        // PA2 = ADC1_IN2
    ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_55Cycles5);        // PA3 = ADC1_IN3
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 4, ADC_SampleTime_55Cycles5);    // PC1 = ADC1_IN11 = Az
    ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 5, ADC_SampleTime_55Cycles5);    // PC2 = ADC1_IN12 = Ax
    ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 6, ADC_SampleTime_55Cycles5);    // PC3 = ADC1_IN13 = Ay

    ADC_Init(ADC1, &ADC_InitStructure);        // Inicia el ADC1

    // Habilita el ADC
    ADC_Cmd (ADC1,ENABLE);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);

    //    Calibración del ADC (opcional, pero recomendado tras arrancar)
    ADC_ResetCalibration(ADC1);    // Resetea la calibración previa
    while(ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);    // Inicia una nueva calibración (el ADC debe estar OFF)
    while(ADC_GetCalibrationStatus(ADC1));
}

I save the 6 signal measurements in a structure, like shows this function:

void Leer_mag(MEDIDA_AG * mag)
{
    // uint16_t medidas[6];
    uint8_t n = 0;

    // CTE_CONVERSION = 3.3 Voltios / 2^12 niveles = 8.05664e-4

    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_STRT) == RESET)
        ;
    ADC_ClearFlag(ADC1, ADC_FLAG_STRT);

    for(n = 0; n < 6; n++)
    {
        while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
            ;
        ADC_ClearFlag(ADC1, ADC_FLAG_EOC);

        //ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
        mag->medidas[n] = ADC_GetConversionValue(ADC1);
    }
}

The problem is that when I check the value of the measurement with DAC and a multimeter, it seems it only reads one signal, not the 6 different signals. I have tried everithing. Must I use DMA or interruptions?

Thanks!!!

Outcomes