Search code examples
adcstm32f1

How to Use the VREFINT in stm32f103 bluepill?


I'm not able to understand the use of VREFINT in stm32f103 board. Can anyone explain me how to get adc value in stm32f103 using VREFINT?

  if(HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK)
  {
      adcVrefInt = HAL_ADC_GetValue(&hadc1);
      vdd = 4095.0 * 1.20 / (float)adcVrefInt;
      vdd += 0.61; // .61 is the difference i'm getting in VDD
      sprintf(buffer, "VREFINT: %ld\tVDD: %.2f\t", adcVrefInt, vdd);
      HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), 100);

      if(HAL_ADC_PollForConversion(&hadc2, 100) == HAL_OK)
      {
          adcValue = HAL_ADC_GetValue(&hadc2);
          adcVoltage = (vdd/4095.0) * adcValue;
          sprintf(buffer, "ADC_PA0: %ld\tVoltage-PA0: %.2f\n", adcValue, adcVoltage);
          HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), 100);
      }
  }

Solution

  • You can read the VREFINT channel (17) much like any other channel on ADC1, after setting the TSVREFE bit in ADC1->CR2. It's an internal analog signal, there is no pin associated with it. VREFINT has a fixed voltage of 1.20 ± 0.04 V.

    If an ADC input pin is connected to VDDA, you get a reading of 4095. If it's connected to VSSA, you get 0. If there is any other voltage V1 between these limits, you get 4095 * V1 / VDDA. This applies to the VREFINT channel as well.

    When you measure VREFINT, ADC1->DR = 4095 * VREFINT / VDDA. Because you know that VREFINT = 1.20V, you can calculate VDDA=4095 * 1.20 / ADC1->DR Volts.