Skip to main content
oleg239955
Associate
April 7, 2015
Question

Stm32f051 adc for multiple channels

  • April 7, 2015
  • 4 replies
  • 1298 views
Posted on April 07, 2015 at 09:14

Hello everyone,

I have problem with the ad conversion into the stm32f051 microcontroller. My Destination is: AD-convert for multiple channels PC0, PC1, PC2, PC3, PB0 und PB1 My Problem:

The

AD values

do not match the

voltage values at

the respective channel

My Code:

// Initalization Reset and clock control (RCC) 
void init_RCC(void) 
{ 
/* GPIO Ports and DMA1 Clock avtivate */ 
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA 
| RCC_AHBPeriph_GPIOB 
| RCC_AHBPeriph_GPIOC 
| RCC_AHBPeriph_GPIOD, ENABLE); 
/* SPI1 and SPI2 Clock activate */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
/* USART clock activate */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 
/* TIM14 clock activate */ 
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE); 
/* ADC clock activate */ 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); 
} 
void init_ADC() 
{ 
/* Structure definition GPIO_InitStruct at GPIO_initTypDef */ 
GPIO_InitTypeDef GPIO_InitStruct; 
/* Structure definition ADC_InitStruct at ADC_initTypDef */ 
ADC_InitTypeDef ADC_InitStruct; 
/* Configure ADC pins : PC0, PC1, PC2, PC3 */ 
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1; 
GPIO_Init(GPIOC, &GPIO_InitStruct); 
/* Configure ADC pins : PB0, PB1 */ 
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; 
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; 
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1; 
GPIO_Init(GPIOB, &GPIO_InitStruct); 
/* Put everythink back to power-on defaults */ 
ADC_DeInit(ADC1); 
/* Initalize ADC structure */ 
ADC_StructInit(&ADC_InitStruct); 
/* ADC-Structure initialization */ 
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; /* After the end of conversion, the next conversion will be started automatically if ENABLE */ 
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; /* Data align into the right from LSB */ 
ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConvEdge_None; /* Data with not external trigger configuration */ 
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; /* ADC resolution from 12 Bit */ 
ADC_InitStruct.ADC_ScanDirection = ADC_ScanDirection_Upward; /* ADC scans the channel upward */ 
ADC_Init(ADC1, &ADC_InitStruct); /* ADC1 initalize with configuration parameters */ 
/* Aktivate ADC */ 
ADC_Cmd(ADC1, ENABLE); 
} 
uint16_t readADC1(uint8_t channel) 
{ 
/* Activate ADC1 in coninous mode */ 
//ADC_DiscModeCmd(ADC1, ENABLE); 
/* Channel configuration */ 
ADC_ChannelConfig(ADC1, channel, ADC_SampleTime_1_5Cycles); 
/* Start the conversion */ 
ADC_StartOfConversion(ADC1); 
/* Wait until conversion completion */ 
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); 
/* Get the conversion value */ 
uint16_t Value = ADC_GetConversionValue(ADC1); 
/* Clear EOC Flag */ 
ADC_ClearFlag(ADC1, ADC_FLAG_EOC); 
return Value; 
} 
int main(void) 
{ 
init_RCC(); /* Reset and Clock Control initialized */ 
init_GPIO(); /* General Purpose Inputs- and Outputs initialized */ 
if (SysTick_Config(SystemCoreClock / reloadValueDiv)) 
{ 
/* Capture error */ 
while (1); 
} 
init_SPI(); /* Serial Peripheral Interface initialized */ 
//init_USART(); /* Universal Synchronous and Asynchronous Receiver Transmitter initialized */ 
init_NVIC(); /* Nested Vectored Interrupt Controller initialized */ 
//init_Timer(); /* Timer initialized */ 
GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET); /* ADC_RESET = nRESET set high */ 
init_ADS8332(ads8332_configuration_setting); /* ADS8332 Initialized with ads8332_configuration_setting*/ 
if((get_ADS8332_configuration() & 0x0FFF) != (ads8332_configuration_setting & 0x0FFF)) /* If the receive ads8332 configuration is not equal, than capture error. */ 
{ 
/* Capture error */ 
while (1); 
} 
GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET); /* ADC_CS = nCS set high */ 
GPIO_WriteBit(GPIOB, GPIO_Pin_12, Bit_SET); /* nCONVST = nCS set high */ 
init_ADC(); /* ADC initialized */ 
while (1) 
{ 
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET); 
for(i=0;i<8;i++){ 
spiDataBufferSPI1[i] = get_ADS8332_adc_value(i); 
} 
for(j=0;j<6;j++){ 
value[j] = readADC1(j); 
} 
/* Wait rest cycle time in this delay-function */ 
Delay(CYCLE_TIME); 
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET); 
} 
}

Please help me,

I

'm new to this

area

. Haak
    This topic has been closed for replies.

    4 replies

    raptorhal2
    Lead
    April 7, 2015
    Posted on April 07, 2015 at 20:17

    In the analog world, it helps to state how much error you are observing.

    1.5 sample time might be too short if you don't have a low impedance signal source. Increase the sample time to the largest value available. If that fixes the problem, decrease the time to whatever still works.

    Cheers, Hal

    oleg239955
    Associate
    April 8, 2015
    Posted on April 08, 2015 at 08:15

    Hello Hal,

    Thank you for

    your

    suggestion.

    1

    ) I have

    the ADC

    Sample

    Time

    increased to

    239.5

    cycles and

    start

    the debug mode

    .

    In the first

    program cycle

    following

    AD

    values

    will be read

    …

    Value[0] = 1053; // The correct

    values

    should be

    2110

    decimal

    Value[1] = 0; // and

    all other values

    would

    also have a

    small offset

    Value[2] = 0;

    Value[3] = 0;

    Value[4] = 0;

    Value[5] = 0;

    and

    in the second and

    higher

    program

    cycles

    following

    values are read

    ...

    Value[0] = 0; // The correct

    values

    should be

    2110

    decimal

    Value[1] = 0; // and

    all other values

    would

    also have a

    small offset

    Value[2] = 0;

    Value[3] = 0;

    Value[4] = 0;

    Value[5] = 0;

    2)

    I have

    the ADC

    Sample

    Time

    increased to

    55.5

    cycles and

    start

    the debug mode

    .

    In the first

    program cycle

    following

    AD

    values

    will be read

    …

    Value[0] = 1054; // The correct

    values

    should be

    2110

    decimal

    Value[1] = 285; // and

    all other values

    would

    also have a

    small offset

    Value[2] = 45;

    Value[3] = 37;

    Value[4] = 31;

    Value[5] = 93;

    and

    in the second and

    higher

    program

    cycles

    following

    values are read

    ...

    Value[0] = 218; // The correct

    values

    should be

    2110

    decimal

    Value[1] = 110; // and

    all other values

    would

    also have a

    small offset

    Value[2] = 104;

    Value[3] = 104;

    Value[4] = 103;

    Value[5] = 108;

    It seems

    as if the

    AD

    values do not

    change with

    changing

    external

    voltage

    . I have pulled the voltage to ground on the PC 0 AD input and received the same value as described above.

    Can

    someone tell me if

    my

    ADC

    Configuration and readADC1()-function

    is correct

    ?

    I want to

    read the

    analog

    channels

    PC0, PC1, PC2, PC3, PB0 and PB1.

    Best regards

    Haak

    raptorhal2
    Lead
    April 8, 2015
    Posted on April 08, 2015 at 15:50

    I am not familiar with the F05, but comparing the code with the data sheet pinout table, it looks like you are trying to convert ADC channels 0 to 5 but set up GPIO pins in analog mode for  channels 10 to 13 (PC0 to PC3) and 8 & 9 (PB0 & PB1).

    Cheers, Hal

    raptorhal2
    Lead
    April 8, 2015
    Posted on April 09, 2015 at 01:43

    I presume you are examining your options at this point.

    Multiple ADC channel conversions are usually saved in a buffer using DMA, rather than reading the ADC conversion register after each conversion. See the Reference Manual and ADC examples on how to do this.

    You posted in an Evaluation Tools forum. If you are using a Discovery or Evaluation board, refer to the board's User Manual to ensure the pins are free for your use.

    Cheers, Hal