cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F042C6U6 ADC Input Problem

Sergen
Associate III

Hello,

I use STM32F042C6U6 processor. I use IN 2, 3 and 4 inputs for ADC, but when I activate channel IN 4 input, there are serious deviations in other ADC values.

My Variable 

uint32_t adc_values[2];

Main Code:

 

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
  HAL_ADCEx_Calibration_Start(&hadc);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
      HAL_ADC_Start(&hadc);
      for (int i = 0; i < 2; i++) {
          HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
          adc_values[i] = HAL_ADC_GetValue(&hadc);
      }

      HAL_ADC_Stop(&hadc);
      HAL_Delay(150);

      // Burada adc_values[] dizisindeki değerler işlenebilir
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

 

My Clock Settings

Sergen_0-1729362040278.png

 

 

3 REPLIES 3

The problem may be in too high impedance of input signal to channels 2 and 3 and/or too short sampling time for them. The value measured by ADC is influenced by the value measured for previous channel, unless the input impedance of the next channel is low enough so that the sampling capacitor is fully charged by the end of the sampling time.

JW

EXUE.2
ST Employee

it is difficult to get the cause from your limit information and code, but before you get ADC value every time, it is better like below example:

HAL_ADC_Start( &ARD_hadc ); // start ADC conversion
while( (ADC1->ISR & ADC_FLAG_EOC) == 0 );

adc_value = HAL_ADC_GetValue( &ARD_hadc );

Saket_Om
ST Employee

Hello @Sergen 

ADC is converting each channel of the sequence, whatever data fetch by CPU or not.
The risk of implemented sequence is that CPU does not get the conversion data on time (for example, due to prememption by another process), and get data corresponding to the following channel.
It is recommended to use DMA to avoid any timing issue.
Example in FW package: ...\Projects\STM32F072RB-Nucleo\Examples\ADC\ADC_Sequencer

Other solution: activate discontinuous mode.

For debug, to identify if timing or not, can you:
- activate discontinuous mode (AdcHandle.Init.DiscontinuousConvMode = ENABLE): one SW trigger start needed by channel in the sequence
- set sampling time to maximum (AdcHandle.Init.SamplingTimeCommon = ADC_SAMPLETIME_239CYCLES_5)

- reduce clock speed (AdcHandle.Init.ClockPrescaler  = ADC_CLOCK_ASYNC_DIV4)

 

Modify the sequence with:
      for (int i = 0; i < 2; i++) {
          HAL_ADC_Start(&hadc);
          HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY);
          adc_values[i] = HAL_ADC_GetValue(&hadc);
      }

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar