cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F030R8Tx ADC Problem?

EFons
Associate II

I do not know if and what I am doing wrong. I am using CubeMX and a Nucleo 64-Board. This is the while inside the main:

while (1)
  {
	  if(HAL_ADC_PollForConversion(&hadc, 1000) == HAL_OK){
		  adc_value[i] = HAL_ADC_GetValue(&hadc);
		  media += ((float)adc_value[i++])/n_amostras;
		  r = 0.02*media;
		  v = 0.04*media;
		  comp = 52.91*media;
		  if(i == n_amostras){
		  		  i = 0;
		  		  media = 0;
		  }
	  }
 
    
  }

I do not know if the PollForConversion is the best option, I just used because I saw it in a tutorial in youtube. I need to calculate these values 'r', 'v' and 'comp'. One of my problems is that the ADC is not so accurate as I would like, I would appreciate suggestions about how I could improve this. Also sometimes it does not work as it should, but this could be a problem in my circuit. the values become random, apparently. I will also show the configuration of the ADC:

static void MX_ADC_Init(void)
{
 
  /* USER CODE BEGIN ADC_Init 0 */
 
  /* USER CODE END ADC_Init 0 */
 
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /* USER CODE BEGIN ADC_Init 1 */
 
  /* USER CODE END ADC_Init 1 */
  /**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_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = ENABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /**Configure for the selected ADC regular channel to be converted. 
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC_Init 2 */
  HAL_ADCEx_Calibration_Start(&hadc);
  /* USER CODE END ADC_Init 2 */
 
}

I also used the calibration function of the HAL library here, but I do not if I am using it in the right way.

4 REPLIES 4

Hi

index i , has always the same value. was this your intention?

if i is different than n_amostras then the inside loop "if" statement will never be true.

S.Ma
Principal

True and also what is the input analog impedence of what is connected... unless there is an external op-amp in follower mode.

Otherwise, ADC result will be lower than expected... and more unstable.

It was not my intention, it is corrected now.

Input impedance, S&H capacity and sampling time are interrelated. I guess you know how to deal with it, design-wise.

I suggest to validate the ADC channels first,, by applying known (and different) voltages to all channels, and check the values - either via some output, or in the debugger.