cancel
Showing results for 
Search instead for 
Did you mean: 

NUCLEO-G431KB, wrong values on ADC channel 4

Heinrich
Associate III

Hello Forum,

I have an issue while reading the values from ADC. ADC1 is running in "continues scan convertion mode" using DMA and 5 ranks.

Here is ADC_Init function:

static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */

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

  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }

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

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_VREFINT;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

Then, here is my main() function:

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_DMA_Init();
  MX_DAC1_Init();
  MX_I2C2_Init();
  MX_USB_Device_Init();
  MX_TIM17_Init();
  MX_CRC_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
  if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED) != HAL_OK)
  {
	  Error_Handler();
  }

  if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_convertions, 5) != HAL_OK)
  {
	  Error_Handler();
  }



  HAL_DAC_Start(&hdac1, DAC1_CHANNEL_1);
  HAL_DAC_Start(&hdac1, DAC1_CHANNEL_2);
  HAL_TIM_Base_Start_IT(&htim17);

  AT24CXX_Init(hi2c2);
  load_configuration();
  init_spline();
  // load_default_configuration();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  timer_tasks_execute();

	  if (received_data)
	  {
		  process_tunerstudio();
		  received_data = false;
	  }
    /* USER CODE END WHILE */

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

The variable adc_convertions is declared as uint32_t adc_convertions[5] = {0};

Issue:

If I apply the a voltage (2.15v) to PA1 and PA3, in adc_convertions array I get the ADC of 2620 for PA1 and 1531 for PA3. But, the both values shold be equal... The another ranks in adc_convertions array are correct.

  • I've tried to change a sample time for CHANNEL4 (= PA3), no success.
  • I removed SB1 and SB12 (because PA3 is connected to STLINK-V3E virtual c omport) , no success.
  • I've tried to map CHANNEL4 to different Rank, no success.

So, 'Ive no idea anymore...

Can you please help me?

Many thanks & regards,
Heinrich

1 ACCEPTED SOLUTION

Accepted Solutions

> If I apply the a voltage (2.15v) to PA1 and PA3

So, are PA1 and PA3 physically connected together?

> I removed SB1 and SB12 (because PA3 is connected to STLINK-V3E virtual c omport)

And did you connect SB14?

JW

View solution in original post

11 REPLIES 11
Karl Yamashita
Lead III

Change your type to uint16_t instead of uint32_t 

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Do you mean the type of adc_convertions[5]?

Regards,
Heinrich

MasterT
Lead

Instead:

if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *) &adc_convertions, 5) != HAL_OK)

try:

if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)  adc_convertions, 5) != HAL_OK)

 

And declaration of : uint32_t adc_convertions[5] = {0}; depends on DMA_word size, what we can't see, since no dma config provided.

> If I apply the a voltage (2.15v) to PA1 and PA3

So, are PA1 and PA3 physically connected together?

> I removed SB1 and SB12 (because PA3 is connected to STLINK-V3E virtual c omport)

And did you connect SB14?

JW

Yes ADC is 12bit then optimal result is 16bit half word DMA and uint16_t array.

And for addressing array right syntax is adc_convertions or &adc_convertions[0] .

Heinrich
Associate III

Hi guys, first of all, thank you very much for help :)

@MasterT:

DMA is configured like this at the moment:

Heinrich_0-1728739610358.png

Since STM32 is a 32-bit MCU, WORD means uint32_t, I think... It is correct?

@waclawek.jan 

Yes, PA1 and PA3 are connected together. Not directly on Nucleo, but on carrier board. The is a voltage divider (5v to 3.3), then buffer and then NUCLEO. AI've applied 3.3v from NUCLEO to both input pins, after voltage diviers and buffers, I get 2.15v on BOTH pins of NUCLEO. So, the hardware should be okay, because the get the same voltage.

No, SB15 is still default, so not "installed".

@MM..1Okay, I've removed & , the DMA is configured as word, not half-word.

What I've done:

  • Remove the & in if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *) adc_convertions, 5) != HAL_OK)
  • Changed uint32_t to uint16_t.

Result:

  • CHANNEL1 (adc_convertions[0]) says 2620, correct.
  • CHANNEL4 (adc_convertions[1]) says 0, normal since SB14 is open...

I will close SB14 a bit later and test it :)

If DMA configured as Word_Peripheral- Word_Memory, than 

uint32_t adc_convertions[5] = {0};  or int32_t adc_convertions[5] = {0};

correct declaration. 

For Halfword_Peripheral- Halfword_Memory, than 

uint16_t adc_convertions[5] = {0};  or int16_t adc_convertions[5] = {0}; 

Okay, then it was correct.

I've changed them back to uint32_t adc_convertions[5] = {0};

and:

  • adc_convertions[0] says 2621, correct
  • adc_convertions[1] says 1543, wrong

I'll test with SB14 closed today evening.

Regards,
Heinrich

sConfig.Channel = ADC_CHANNEL_VREFINT;
  sConfig.Rank = ADC_REGULAR_RANK_2;

why you mean this must equal RANK_1 ? And for effectivity set DMA to half word and array to uint16 ...