cancel
Showing results for 
Search instead for 
Did you mean: 

VDDA and PA2 ADC measurements

Jérémy Da Silva
Associate II
Posted on August 30, 2017 at 15:48

Hello,

I work on a STM32L151CCU6 and I need your help.

I try to measure VDDA voltage in order to calculate a voltage divider on PA2 (single mode). My two ADC configuration functions are :

void MX_ADC_Init(void)

{

  GPIO_InitTypeDef gpioInit1;

  GPIO_InitTypeDef gpioInit2;

   

    gpioInit1.Pin = PID_PIN; //PA2

    gpioInit1.Mode = GPIO_MODE_ANALOG;

    gpioInit1.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(PID_PORT, &gpioInit1); PA2

    

    gpioInit2.Pin = PID_POWER_SUPPLY_PIN; //PB2

    gpioInit2.Mode = GPIO_MODE_OUTPUT_PP;

    gpioInit2.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(PID_POWER_SUPPLY_PORT, &gpioInit2); //PB2

    

  __HAL_RCC_ADC1_CLK_ENABLE();

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

    */

  adc_identification.Instance = ADC1;

  adc_identification.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2;

  adc_identification.Init.Resolution = ADC_RESOLUTION_12B;

  adc_identification.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  adc_identification.Init.ScanConvMode = ADC_SCAN_DISABLE;

  adc_identification.Init.EOCSelection = ADC_EOC_SEQ_CONV;

  adc_identification.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;

  adc_identification.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;

  adc_identification.Init.ChannelsBank = ADC_CHANNELS_BANK_A;

  adc_identification.Init.ContinuousConvMode = DISABLE;

  adc_identification.Init.NbrOfConversion = 1;

  adc_identification.Init.DiscontinuousConvMode = DISABLE;

  adc_identification.Init.ExternalTrigConv = ADC_SOFTWARE_START;

  adc_identification.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  adc_identification.Init.DMAContinuousRequests = DISABLE;

  if (HAL_ADC_Init(&adc_identification) != HAL_OK)

  {

    while(1);

  }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

    */

  sConfig.Channel = ADC_CHANNEL_2;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_384CYCLES;

  if (HAL_ADC_ConfigChannel(&adc_identification, &sConfig) != HAL_OK)

  {

    while(1);

  }

  ADC_Enable(&adc_identification);

}

and :

void MX_ADC_VDD_Init(void)

{

  ADC_ChannelConfTypeDef sConfig;

 

  /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)*/

  VDD_measurement.Instance = ADC1;

  VDD_measurement.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

  VDD_measurement.Init.Resolution = ADC_RESOLUTION_12B;

  VDD_measurement.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  VDD_measurement.Init.ScanConvMode = ADC_SCAN_DISABLE;

  VDD_measurement.Init.EOCSelection = ADC_EOC_SEQ_CONV;

  VDD_measurement.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;

  VDD_measurement.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;

  VDD_measurement.Init.ChannelsBank = ADC_CHANNELS_BANK_A;

  VDD_measurement.Init.ContinuousConvMode = DISABLE;

  VDD_measurement.Init.NbrOfConversion = 1;

  VDD_measurement.Init.DiscontinuousConvMode = DISABLE;

  VDD_measurement.Init.ExternalTrigConv = ADC_SOFTWARE_START;

  VDD_measurement.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  VDD_measurement.Init.DMAContinuousRequests = DISABLE;

  if (HAL_ADC_Init(&VDD_measurement) != HAL_OK)

  {

    while(1);

  }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

    */

  sConfig.Channel = ADC_CHANNEL_17;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_4CYCLES;

  if (HAL_ADC_ConfigChannel(&VDD_measurement, &sConfig) != HAL_OK)

  {

    while(1);

  }

  ADC_Enable(&VDD_measurement);

}

When I try to measure this two ADC channel, I find 0.

I use this function : HAL_ADC_GetValue(&VDD_measurement);

Does anyone know where is my problem?

Thanks,

Jérémy

4 REPLIES 4
Posted on August 30, 2017 at 20:45

Hello!

>>> I use this function : HAL_ADC_GetValue(&VDD_measurement);

This function gets converted value only.

Also your ADC_SAMPLETIME_4CYCLES is small.  My suggestion is to increase it at least to ADC_SAMPLETIME_96CYCLES  and after you have a success reading try to calculate the exact timing.

Try to use

uint32_t vdda;

#define VREFINT_CAL_ADDR ((uint16_t*) (0x1FF800F8U)) /* Internal voltage reference,

#define VREFINT_CAL_VREF                   ( 3000U)                    /* Analog voltage reference

HAL_ADC_Start(&VDD_measurement);

vdda=VREFINT_CAL_VREF*(*VREFINT_CAL_ADDR);//VDDA = 3 V x VREFINT_CAL / VREFINT_DATA

HAL_ADC_PollForConversion(&VDD_measurement, 1000);

vdda /=HAL_ADC_GetValue(&VDD_measurement);

The vdda value will be in millivolts.

0690X0000060858QAA.png

Use the same way to read the PA2  Start, Wait, Read.

Regards

vf

Posted on August 31, 2017 at 10:42

Hello!

Thank you ! That is working well for VDDA but not for PA2.

I have changed the Init function like below:

void MX_ADC_Init(void)

{

  GPIO_InitTypeDef gpioInit1;

  GPIO_InitTypeDef gpioInit2;

   

    gpioInit1.Pin = PID_PIN;  //PA2

    gpioInit1.Mode = GPIO_MODE_ANALOG;

    gpioInit1.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(PID_PORT, &gpioInit1);

    

    gpioInit2.Pin = PID_POWER_SUPPLY_PIN;  //PB2

    gpioInit2.Mode = GPIO_MODE_OUTPUT_PP;

    gpioInit2.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(PID_POWER_SUPPLY_PORT, &gpioInit2);

    

  __HAL_RCC_ADC1_CLK_ENABLE();

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

    */

  adc_identification.Instance = ADC1;

  adc_identification.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

  adc_identification.Init.Resolution = ADC_RESOLUTION_12B;

  adc_identification.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  adc_identification.Init.ScanConvMode = ADC_SCAN_DISABLE;

  adc_identification.Init.EOCSelection = ADC_EOC_SEQ_CONV;

  adc_identification.Init.LowPowerAutoWait = ADC_AUTOWAIT_UNTIL_DATA_READ;

  adc_identification.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;

  adc_identification.Init.ChannelsBank = ADC_CHANNELS_BANK_A;

  adc_identification.Init.ContinuousConvMode = DISABLE;

  adc_identification.Init.NbrOfConversion = 1;

  adc_identification.Init.DiscontinuousConvMode = DISABLE;

  adc_identification.Init.ExternalTrigConv = ADC_SOFTWARE_START;

  adc_identification.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  adc_identification.Init.DMAContinuousRequests = DISABLE;

  if (HAL_ADC_Init(&adc_identification) != HAL_OK)

  {

    while(1);

  }

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

    */

  sConfig.Channel = ADC_CHANNEL_2;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES;

  if (HAL_ADC_ConfigChannel(&adc_identification, &sConfig) != HAL_OK)

  {

    while(1);

  }

  ADC_Enable(&adc_identification);

}

And I read the value of the voltage like :

void ADC_Measure(ADC_HandleTypeDef* hadc)

{

        MX_ADC_Init(); //Init ADC

        ADC_PowerOnPin(); //Enable the 3.3V of the voltage divider

        ADC_Start(hadc);

        HAL_ADC_PollForConversion(hadc, 1000);

        ADC_Measure_ID =HAL_ADC_GetValue(hadc);

        ADC_PowerOffPin(); //Disable the 3.3V of the voltage divider

        ADC_Stop(hadc);

}

But I receive 0. I use exactly the same parameters in initialization as for VDD and the same measurement function too.

Any idea for this point?

Thank you for your help.

Jérémy Da Silva
Associate II
Posted on September 04, 2017 at 10:22

Hello,

Any ideas?

Thank you.

Posted on September 04, 2017 at 17:11

Hi

in GPIO initialization function the GPIO clock seems not enabled.

__HAL_RCC_GPIOX_CLK_ENABLE();