cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with STM32L0 Basic ADC Operation

RSoen.1
Associate III

I am having trouble getting the ADC to work right in basic polled operation. I am polling two channels which provide voltages via resistor dividers. I have measured the voltages at the ADC inputs and they are correct so I do not believe the divider impedances are too high.

I get an ADC result that does not vary much. For example I get around 420 counts (out of 4096) with 0.9V at the input. With that voltage I should see ~1100 counts. And the result does not seem to vary with voltage...

Here is my setup, I would appreciate any advice.

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.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc.Init.LowPowerAutoWait = ENABLE;
  hadc.Init.LowPowerFrequencyMode = ENABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted.
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure for the selected ADC regular channel to be converted.
  */
  sConfig.Channel = ADC_CHANNEL_2;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC_Init 2 */
 
 
 
  /* USER CODE END ADC_Init 2 */
 
}

This is called periodically:

uint16_t adcGetVolt(void)
{
  volatile float V = 0;
 
  // Get ADC value
  adcConfig.Channel = ADC_CHANNEL_2;
  HAL_ADC_ConfigChannel(&hadc, &adcConfig);
  HAL_ADC_Start(&hadc);
  HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
  sampleValue = HAL_ADC_GetValue(&hadc);
 
  V = ((((float)sampleValue/4096.0f) * 3.30f) / VOLT_DIVIDER_MULTIPLIER);//.0697
 
  volts_average = V;
  return((uint16_t)((volts_average*10.0f) + 0.5f));
 
}

Alway returns ~420 counts

and also:

int16_t read_temperature(void)
{
		float v, i, r, temperature_low, temperature_high, temperature, delta;
		int char_index;
		int16_t temp, temp_single;
//		bool no_thermistor = false;
 
		  adcConfig.Channel = ADC_CHANNEL_0;
		  HAL_ADC_ConfigChannel(&hadc, &adcConfig);
		  HAL_ADC_Start(&hadc);
		  HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
		  sampleValue2 = HAL_ADC_GetValue(&hadc);

Also always returns ~420 counts

This discussion is locked. Please start a new topic to ask your question.
4 REPLIES 4
RSoen.1
Associate III

I have VDDA tied to 3.3V so that is the reference for the ADC correct?

Anyone know of an ADC (simple polling) for the L0 series? I cannot find any in the import examples in STM32CUBE ide...

Javier1
Principal

my aracnosense tells me the problem is here:

  V = ((((float)sampleValue/4096.0f) * 3.30f) / VOLT_DIVIDER_MULTIPLIER);//.0697

you can start your debugg session and screen your sampleValue variable and see if its good.

hit me up in https://www.linkedin.com/in/javiermu%C3%B1oz/
Ozone
Principal

I would attach a potentiometer to the ADC input and vary the input between 0...3.3V.

Take care to keep the input impedance low enough, I would not exceed 10k Ohm.

> my aracnosense tells me the problem is here: ...

That could be true.

The C type promotion rules are confusing at times.

And there are floats and integers involved.

I would split up the combined calculation in multiple expressions first, and check the proper result of each operation.

waclawek.jan
Super User

Which pin and which STM32 exactly?

Read out and check/post content of ADC and relevant GPIO registers content, at the moment when you read out the converted result.

JW