Skip to main content
Jérémy Da Silva
Associate II
August 30, 2017
Question

VDDA and PA2 ADC measurements

  • August 30, 2017
  • 2 replies
  • 1094 views
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

    This topic has been closed for replies.

    2 replies

    Vangelis Fortounas
    Associate II
    August 30, 2017
    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

    Jérémy Da Silva
    Associate II
    August 31, 2017
    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
    September 4, 2017
    Posted on September 04, 2017 at 10:22

    Hello,

    Any ideas?

    Thank you.

    Vangelis Fortounas
    Associate II
    September 4, 2017
    Posted on September 04, 2017 at 17:11

    Hi

    in GPIO initialization function the GPIO clock seems not enabled.

    __HAL_RCC_GPIOX_CLK_ENABLE();