cancel
Showing results for 
Search instead for 
Did you mean: 

why does ADC_FLAG_EOS get called after each channel?

Scott Dev
Senior
Posted on April 06, 2017 at 12:22

Hi

I am trying to use the ADC in the STM32L07 as a multichannel scan. I have set up Cube for 3 analogue channels, AN0, Temperature and VRef Int. I have set it up for single scan usign the HAL_ADC_Start_IT(&hadc); command. Within the interupt routine I am checking the ADC_FLAG_EOC for after each channel completed, and the ADC_FLAG_EOS for after the complete scan is completed. When the HAL_ADC_Start_IT is called, I see the first channel with ADC_FLAG_EOC, but straight away the ADC_FLAG_EOS is also called. I am new to the chip, and not sure what I am doing wrong, can anyone advice me? My code is below, and attached is snap shot of the cube setting

Many Thanks

Scott

unsigned ADC_Raw[3];

unsigned char ADC_index=0;

#define AD_VCCINT 2

#define AD_TEMP 1

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

{

if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC))

{

ADC_Raw[ADC_index++]=HAL_ADC_GetValue(hadc);

ADC_raw = HAL_ADC_GetValue(hadc);

}

if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))

{ <<gets called straight after first conversion...

ADC_index=0;

Vdd = 3000 * (*VREFINT_CAL_ADDR)/ADC_Raw[AD_VCCINT];

temperature=(((int32_t)ADC_Raw[AD_TEMP]*Vdd/3000)-(int32_t)*TEMP30_CAL_ADDR);

temperature*=(int32_t)(130-30);

temperature/=(int32_t)(*TEMP130_CAL_ADDR - *TEMP30_CAL_ADDR);

temperature+=30;

}

}

static void MX_ADC_Init(void)

{

ADC_ChannelConfTypeDef sConfig;

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

*/

hadc.Instance = ADC1;

hadc.Init.OversamplingMode = DISABLE;

hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;

hadc.Init.Resolution = ADC_RESOLUTION_12B;

hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

hadc.Init.ContinuousConvMode = DISABLE;

hadc.Init.DiscontinuousConvMode = DISABLE;

hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

hadc.Init.DMAContinuousRequests = DISABLE;

hadc.Init.EOCSelection = ADC_EOC_SINGLE_SEQ_CONV;

hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

hadc.Init.LowPowerAutoWait = DISABLE;

hadc.Init.LowPowerFrequencyMode = DISABLE;

hadc.Init.LowPowerAutoPowerOff = DISABLE;

if (HAL_ADC_Init(&hadc) != HAL_OK)

{

Error_Handler();

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_0;

sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

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

{

Error_Handler();

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;

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

{

Error_Handler();

}

/**Configure for the selected ADC regular channel to be converted.

*/

sConfig.Channel = ADC_CHANNEL_VREFINT;

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

{

Error_Handler();

}

}

Note: this post was migrated and contained many threaded conversations, some content may be missing.
28 REPLIES 28
howard n2wx
Senior
Posted on April 06, 2017 at 15:57

[Speculation] When the callback gets to this bit

if (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS))

the conversion sequence is all done?

Posted on April 06, 2017 at 16:13

Hi

  I have placed a breakpoint at the start of the interupt, and was expected to the ADC_FLAG_EOC routine to be carried out 3 times, then on the last convertion the ADC_FLAG_EOS be done. But what I am seeing is that the ADC_FLAG_EOC is being carried out and straight away the ADC_FLAG_EOS being carried out too.  I only called the HAL_ADC_Start_IT(&hadc); once so I know what I should be seeing.

I was looking at UM1749,STM32L0 HAL user manual, and it has the description below of the __HAL_ADC_GET_FLAG, but indicates it returns nothing.

Regards

Scott

__HAL_ADC_GET_FLAG Description:

Get the selected ADC's flag

status.

Parameters:

__HANDLE__: ADC handle.

__FLAG__: ADC flag.

Return value:

None
Posted on April 06, 2017 at 16:42

Is the note in UM1749 for HAL_ADC_GetValue() relevant?

If sequencer is composed of 1 rank, flag EOS is equivalent to flag EOC
Posted on April 06, 2017 at 16:51

 hadc.Init.EOCSelection = ADC_EOC_SINGLE_SEQ_CONV;

FWIW the ADC_EOC_SINGLE_SEQ_CONV constant is marked RFU at page 99...

Posted on April 06, 2017 at 16:59

 As im still learning htis chip, I assume the Rank is the position of Scan? I assume the note is only relevant if Im sampling 1 channel, but I am reading 3 in total , as below. But I notice there is only 1 rank added by Cube, in the first one. So would this cause it?

Thanks

Scott

sConfig.Channel = ADC_CHANNEL_0;

  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

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

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;

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

  {

    Error_Handler();

  }

    /**Configure for the selected ADC regular channel to be converted.

    */

  sConfig.Channel = ADC_CHANNEL_VREFINT;

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

  {

    Error_Handler();

  }
Posted on April 06, 2017 at 17:03

Sorry I misread the code, the rank is the same on all channels. And I assume it indicates the channel is the rank number?

Posted on April 06, 2017 at 17:14

Thanks.  I saw this, and its set to this too. I am just stuck to see what the issue can be

Posted on April 06, 2017 at 17:48

I see the define for the below is marked reserved for future use, but cubemx has the selection and created the code.

&sharpdefine ADC_EOC_SINGLE_SEQ_CONV     ((uint32_t)(ADC_ISR_EOC | ADC_ISR_EOS))  /*!< reserved for future use */

Posted on April 06, 2017 at 17:57

Are any of the other channels even converting?  Maybe set ranks in ascending order starting with 1 on all of your channels and for EOCSelection set that puppy to ADC_EOC_SINGLE_CONV because you want discrete ints for EOC and EOS.

As im still learning htis chip

That's cool, me too.  I'm only up on the F3 and LL/std periph drivers