cancel
Showing results for 
Search instead for 
Did you mean: 

ADC configuration with PC0 and PA0

Kelsey Josund
Associate
Posted on June 23, 2017 at 06:31

I recognize that this is probably a dumb question but I'm really struggling with it. I've successfully configured ADCs for reads when using PA0 and PA1:

void

ADC_Setup

() {

GPIO_InitTypeDef GPIO_InitStructure;

ADC_InitTypeDef ADC_InitStructure;

ADC_CommonInitTypeDef ADC_CommonInitStructure;

// enable clocks for GPIO and ADC

RCC_AHB1PeriphClockCmd

(RCC_AHB1Periph_GPIOA, ENABLE);

RCC_APB2PeriphClockCmd

(RCC_APB2Periph_ADC1, ENABLE);

// configure PA0, PA1 as alternate function inputs

GPIO_StructInit

(&GPIO_InitStructure);

GPIO_InitStructure.

GPIO_Speed

= GPIO_Speed_2MHz;

GPIO_InitStructure.

GPIO_Mode

= GPIO_Mode_AIN;

GPIO_InitStructure.

GPIO_PuPd

= GPIO_PuPd_NOPULL;

GPIO_InitStructure.

GPIO_Pin

= GPIO_Pin_0 | GPIO_Pin_1;

GPIO_Init

(GPIOA, &GPIO_InitStructure);

// ADC1 configuration

ADC_CommonStructInit

(&ADC_CommonInitStructure);

ADC_CommonInitStructure.

ADC_Mode

= ADC_Mode_Independent;

ADC_CommonInitStructure.

ADC_Prescaler

= ADC_Prescaler_Div2;

ADC_CommonInitStructure.

ADC_DMAAccessMode

= ADC_DMAAccessMode_Disabled;

ADC_CommonInitStructure.

ADC_TwoSamplingDelay

= ADC_TwoSamplingDelay_5Cycles;

ADC_CommonInit

(&ADC_CommonInitStructure);

ADC_StructInit

(&ADC_InitStructure);

ADC_InitStructure.

ADC_Resolution

= ADC_Resolution_12b;

ADC_InitStructure.

ADC_ScanConvMode

= DISABLE;

ADC_InitStructure.

ADC_ContinuousConvMode

= DISABLE;

ADC_InitStructure.

ADC_ExternalTrigConvEdge

= ADC_ExternalTrigConvEdge_None;

ADC_InitStructure.

ADC_DataAlign

= ADC_DataAlign_Right;

ADC_InitStructure.

ADC_NbrOfConversion

=

1

;

ADC_Init

(ADC1, &ADC_InitStructure);

ADC_Cmd

(ADC1, ENABLE);

}

uint16_t

ADC_GetChannel

(

uint8_t

channel) {

ADC_RegularChannelConfig

(ADC1, channel,

1

, ADC_SampleTime_84Cycles);

// Start the conversion

ADC_SoftwareStartConv

(ADC1);

// Wait until conversion completion

while

(

ADC_GetFlagStatus

(ADC1, ADC_FLAG_EOC) == RESET);

// Get the conversion value

return

ADC_GetConversionValue

(ADC1);

}

define

CUTOFF_FREQUENCY

10

// Hz

// low-pass filter works using precomputed alpha = 0.5

uint16_t

filterVoltageFast

(

uint16_t

oldVal,

uint16_t

newSample) {

return

oldVal + ((newSample - oldVal) >>

1

);

}

void

ADC_Poll

(

volatile

ADC_Value *adc) {

adc->brake[

1

] =

ADC_GetChannel

(

0

);

adc->throttle[

1

] =

ADC_GetChannel

(

1

);

adc->brake[

1

] =

filterVoltageFast

(adc->brake[

1

],

ADC_GetChannel

(

0

));

adc->brake[

0

] = adc->brake[

1

];

adc->throttle[

1

] =

filterVoltageFast

(adc->throttle[

1

],

ADC_GetChannel

(

1

));

adc->throttle[

0

] = adc->throttle[

1

];

}

Which works. Now I'm trying to convert this to work with PA0 and PC0 for the same functionality, just with different pins, and I can't figure out where I'm going wrong. With PA0 and PA1 code

 does a bit of additional checks with the low pass filter but I've stripped this down to as little as I think it should be able to get by with, and no dice. Currently it reads kind of random values no matter what voltage I apply to the pin.

void dev_adc_setup() {

    GPIO_InitTypeDef            GPIO_InitStructure_Throttle;

    GPIO_InitTypeDef            GPIO_InitStructure_Brake;

    ADC_InitTypeDef             ADC_InitStructure;

    ADC_CommonInitTypeDef       ADC_CommonInitStructure;

    

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

    ADC_DeInit();

    

    // THROTTLE GPIO SETUP //

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_StructInit(&GPIO_InitStructure_Throttle);

    GPIO_InitStructure_Throttle.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_InitStructure_Throttle.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_InitStructure_Throttle.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_InitStructure_Throttle.GPIO_Pin = GPIO_Pin_0;

    GPIO_Init(GPIOA, &GPIO_InitStructure_Throttle);

    // BRAKE GPIO SETUP //

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

 

    GPIO_StructInit(&GPIO_InitStructure_Brake);

    GPIO_InitStructure_Brake.GPIO_Speed = GPIO_Speed_2MHz;

    GPIO_InitStructure_Brake.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_InitStructure_Brake.GPIO_PuPd = GPIO_PuPd_NOPULL;

    GPIO_InitStructure_Brake.GPIO_Pin = GPIO_Pin_0;

    GPIO_Init(GPIOC, &GPIO_InitStructure_Throttle);

    // ADC1 configuration

    ADC_CommonStructInit(&ADC_CommonInitStructure);

    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;

    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;

    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;

    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;

    ADC_CommonInit(&ADC_CommonInitStructure);

    ADC_StructInit(&ADC_InitStructure);

    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;

    ADC_InitStructure.ADC_ScanConvMode = DISABLE;

    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_NbrOfConversion = 1;

    ADC_Init(ADC3, &ADC_InitStructure);

    ADC_Cmd(ADC3, ENABLE);

}

uint16_t dev_readADC(uint8_t channel)

{

 ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_84Cycles);

  // start the conversion

  ADC_SoftwareStartConv(ADC1);

  // wait until conversion completion

  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);

  // get the conversion value

  return ADC_GetConversionValue(ADC1);

  }

#adc-init #adc-reads #adc #stm32f4-adc #adc-config #adc-stm32 #adc-help
2 REPLIES 2
AvaTar
Lead
Posted on June 23, 2017 at 09:27

The ADC initialization differs slightly between families.

It would be helpful if you report which STM32 device exactly you are working on.

AvaTar
Lead
Posted on June 23, 2017 at 09:34

Without knowledge of the exact device:

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO

A

, ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

When using PC0, you need to enable port C as well.