AnsweredAssumed Answered

STM32F042 Vrefint reading

Question asked by Gursoy.Ali_Ergin on Jun 21, 2016
Latest reply on Aug 17, 2016 by Gursoy.Ali_Ergin
Hi everyone,

I am working on a project and need to measure analog voltage on some channels. To do so I use CubeMx version 4.15.1, but the readings on channels are significantly different than the applied voltage (about 40mV to 100mV). So I decided to use Vrefint to calculate the more accurate result where it is written in the reference manual as:

Vchannel_x = (3.3 * Vrefint_cal * ADC_Data) / (Vrefint_data * Fullscale)

Unfortunately, I always read the Vrefint as 4095. I could not figure it out what I am doing wrong. Could you please guide me to right path?

The HSI14 is used to clock ADC, and I wish to start and stop the conversion. So the initialization of system clock and adc are like:

/* ADC init function */
void MX_ADC_Init(void)
{
     /* Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
      */
     hadc.Instance = ADC1;
     hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
     hadc.Init.Resolution = ADC_RESOLUTION12b;
     hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
     hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
     hadc.Init.EOCSelection = EOC_SINGLE_CONV;
     hadc.Init.LowPowerAutoWait = DISABLE;
     hadc.Init.LowPowerAutoPowerOff = DISABLE;
     hadc.Init.ContinuousConvMode = DISABLE;
     hadc.Init.DiscontinuousConvMode = DISABLE;
     hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
     hadc.Init.DMAContinuousRequests = DISABLE;
     hadc.Init.Overrun = OVR_DATA_PRESERVED;

     if (HAL_ADC_Init(&hadc) != HAL_OK)
     {
          Error_Handler();
     }

     sConfig.Channel = ADC_CHANNEL_VREFINT;
     sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
     sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
     if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
     {
          Error_Handler();
     }
}

/* System Clock Configuration
 */
void SystemClock_Config(void)
{
     RCC_OscInitTypeDef RCC_OscInitStruct;
     RCC_ClkInitTypeDef RCC_ClkInitStruct;
     RCC_PeriphCLKInitTypeDef PeriphClkInit;

     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14
                                   |RCC_OSCILLATORTYPE_LSI;
     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
     RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
     RCC_OscInitStruct.HSICalibrationValue = 16;
     RCC_OscInitStruct.HSI14CalibrationValue = 16;
     RCC_OscInitStruct.LSIState = RCC_LSI_ON;
     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
     {
       Error_Handler();
     }

     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                   |RCC_CLOCKTYPE_PCLK1;
     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
     {
       Error_Handler();
     }

     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_RTC;
     PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
     PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
     {
         Error_Handler();
     }

     HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
     HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

     /* SysTick_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}


int main(void)
{
     /* here I am collecting the adc converted value and calculate the average
      */
     if (getChannelConvertedValue(ADC_CHANNEL_VREFINT, adc_samp_arr, SAMPLE_ARRAY_LENGTH, MEDIAN_LENGTH, &adc_supply_voltage) == RC_OK)
     {
     }
}

RC_TypeDef getChannelConvertedValue(uint32_t channel, uint16_t array[], uint32_t len, uint32_t median_len, float *value)
{
     if (value == NULL)
     {
          return RC_NULL_ARG;
     }

     /* initialize the memory area of the channel
      */
     int i;
     for (i = 0; i < 99; i++)
     {
          array[i] = 0;
     }

     uint16_t adc_val = 0;
     for (i = 0; i < 33; i++)
     {
          HAL_ADCEx_Calibration_Start(&hadc);

          if (HAL_ADC_Start(&hadc) == HAL_OK)
          {
               HAL_ADC_PollForConversion(&hadc, 100);
               adc_val = HAL_ADC_GetValue(&hadc);
               HAL_ADC_Stop(&hadc);
          }
     }


     for (i = 0; i < 99; i++)
     {
          HAL_ADCEx_Calibration_Start(&hadc);

          if (HAL_ADC_Start(&hadc) == HAL_OK)
          {
               HAL_ADC_PollForConversion(&hadc, 1000);

               adc_val = HAL_ADC_GetValue(&hadc);

               HAL_ADC_Stop(&hadc);

               array[i] = adc_val;
          }
          else
          {
               *value = 0;

               return RC_NOT_OK;
          }
     }


     /* store the converted value
      */
     *value = MedianAverage(array, len, median_len);

     return RC_OK;
}


Outcomes