cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32f051 adc for multiple channels

oleg239955
Associate
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
4 REPLIES 4
raptorhal2
Lead
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
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
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
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