cancel
Showing results for 
Search instead for 
Did you mean: 

ADC: How to read 6 signals?

alesuafer1
Associate II
Posted on November 25, 2011 at 13:16

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 anal�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!!!

#adc-stm32-discovery
5 REPLIES 5
Posted on November 25, 2011 at 14:58

You'll definitely need to enable the GPIO clocks before configuring the pins.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
raptorhal2
Lead
Posted on November 29, 2011 at 18:33

And, yes, you need to use DMA to convert more than one ADC channel.

See the STM32 Forum post by Parag dated Oct 10 for more information.

Cheers, Hal

alesuafer1
Associate II
Posted on December 01, 2011 at 12:23

I have another question. If I want to use 6 ADC1 channels, then the EOC (End Of Conversion) flag/interruput is set for every channel conversion or for the whole 6 channel conversion??? Because if the EOC is set every time ADC finishes a channel conversion, then I can read separately every signal.

raptorhal2
Lead
Posted on December 01, 2011 at 19:12

When you use DMA, you set up a six word buffer to store the results, and wait for conversion complete (or do something else useful during conversion). Then each signal is available to read in its buffer location.

Since you are sampling every 20 msec, I doubt you need to grab each signal immediately when it's conversion is complete.

Cheers, Hal

alesuafer1
Associate II
Posted on December 05, 2011 at 15:14

Thank you so much! Finally I was able to read the 6 signals usign DMA.