cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767 ADC with 4 channels regular group missing sample.

Bruno Brentegani
Associate II

Hi all, as mentioned in the title i have an issue with the ADC configured to sampling 4 channels with different rank.

I want to collect the sample in one array ( array uint16_t values[4] ) in the same order for each conversion done. The data in the array are correct, but the position in the array of the data change continuosly, like a swapping. Can someone help me?

I don't want fow now use DMA, i want to learn to manage properly this basic things before.

Thank you all.

This is my code:

/* ADC Config */

 ADC_ChannelConfTypeDef sConfig;

  /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 

  */

 hadc1.Instance = ADC1;

 hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;

 hadc1.Init.Resolution = ADC_RESOLUTION_12B;

 hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;

 hadc1.Init.ContinuousConvMode = DISABLE;

 hadc1.Init.DiscontinuousConvMode = DISABLE;

 hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc1.Init.NbrOfConversion = 4;

 hadc1.Init.DMAContinuousRequests = DISABLE;

 hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 if (HAL_ADC_Init(&hadc1) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

 /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */

 sConfig.Channel = ADC_CHANNEL_10;

 sConfig.Rank = ADC_REGULAR_RANK_1;

 sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

sConfig.Channel = ADC_CHANNEL_11;

 sConfig.Rank = ADC_REGULAR_RANK_2;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

sConfig.Channel = ADC_CHANNEL_12;

 sConfig.Rank = ADC_REGULAR_RANK_3;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

sConfig.Channel = ADC_CHANNEL_13;

 sConfig.Rank = ADC_REGULAR_RANK_4;

 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)

 {

  _Error_Handler(__FILE__, __LINE__);

 }

I start the ADC with "HAL_ADC_Start_IT(&hadc1);" command and the interrupt functions contains this code :

/* ADC Interrupt Get values */

void ADC_IRQHandler(void)

{

values[i] = ADC1->DR; // already try with values[i]= HAL_ADC_GetValue(&hadc1);

i=i+1;

if(i==4)

{

i=0;

}

 HAL_ADC_IRQHandler(&hadc1);

}

values is array of 4 elements uint16_t

2 REPLIES 2
TDK
Guru

The ADC completes 4 conversions in a very short duration and your code is not able to keep up with that.

You can look into discontinuous mode if you want to convert only 1 channel per trigger.

If you feel a post has answered your question, please click "Accept as Solution".
raptorhal2
Lead

The ADC has only one register to store conversion results. NbrOfConversion greater than 1 works only with DMA. For single conversions, configure the numbers.Config.Channel RANK_1 with the next channel for the next conversion.

After you achieve your understanding, look at ST's L4 example Nucleo-L4P5ZG ADC_Sequencer for ADC DMA guidance.

Cheers, Hal