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 */ }
View more

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 */ }
View more

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 ...