cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G431KB ADC Wrong value

cppoisson
Associate II

Hi everyone,

I am using the ADC2 of the STM32G431KB to read a voltage value. I am actualy measuring 0.8V on the pin of the ADC with a multimeter, but while debuging, the conversion give me back 0.12V (~150 from the ADC, instead of ~1000). 

This is my config and the way I do the conversion. 

void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */

  /** Common config
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc2.Init.GainCompensation = 0;
  hadc2.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;  
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = ENABLE; 
  hadc2.Init.NbrOfConversion = 2;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc2.Init.DMAContinuousRequests = ENABLE;
  hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc2.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_VOPAMP2;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_VOPAMP3_ADC2;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  if(HAL_ADCEx_Calibration_Start(&hadc2, ADC_SINGLE_ENDED) != HAL_OK){
    Error_Handler();
  }


  /* USER CODE BEGIN ADC2_Init 2 */
  HAL_ADC_Start_DMA(&hadc2, (uint32_t *) &analog_input.unmap[2], 2);
  /* USER CODE END ADC2_Init 2 */

}

float ll_motor_GetVoltage(void) {
    return (((float)analog_input.voltage * VREF_ADC) / (ADC_RESOLUTION));
}

The input_voltage is linked to the first chanel (VOPAMP 2) of the ADC and put in analog_input.unmap[2] by the dma. 
VREF_ADC = 3.3f
ADC_RESOLUTION = 4096 (12bits)


Do you have an idea on the wrong value origin ? 

Best regards,

Clément.

13 REPLIES 13

Duplicate?

https://community.st.com/t5/stm32-mcus-products/stm32g431kb-adc-wrong-value/td-p/720375

 


@cppoisson wrote:

the ADC is not giving back the right voltage value (which is 0.8V measured with a multimeter) !


So what value is it giving?

Note that a multimeter will give a (relatively) long-term averaged reading, whereas the ADC will give an instantaneous sample ...

 

See also: https://community.st.com/t5/stm32-mcus-boards-and-hardware/adc-voltage-drop/m-p/722300 

I created a new topic because I found new details on the problem that I don't undertstand. I didn't notify that if disabled the ContinuousConvMode I had the wright value on the ADC (900 on the ADC equal to 790mV), but the value is not updated. When I am using the ContinuousConvMode the value from the ADC is 150 so 120mV, but this value is updated. 

I also measure the voltage with the osciloscope, I also found a DC 800mV Voltage.


@cppoisson wrote:

I created a new topic because I found new details on the problem 


It makes more sense keep all of the details of the problem in one place, and all of the existing contributors informed.

Merged into the original thread

MasterT
Lead

I noticed 

  HAL_ADC_Start_DMA(&hadc2, (uint32_t *) &analog_input.unmap[2], 2);

 

correct code to call adc_dma:

  if (HAL_ADC_Start_DMA(&hadc2, (uint32_t *)inp_1, (2 * INP_BUFF)) != HAL_OK) {

 

 If you post how analog_input.unmap[2] declared in the initial post it would be easier to spot software error.