cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L151 ADC in scan mode

MAlle.17
Associate

Hi,

I'm trying to use the ADC1 of the STM32L151CBT6A in scan mode for 14 channels (with interrupt) .

Depending on ADC clock and SamplingTime configuration I got only a channel on 2. If I put sampling time lower than 96 cylces (for prescaler 4) I have :

adcValue[0]=Channel 0

adcValue[1]=Channel 2

adcValue[2]=Channel 4

adcValue[3]=Channel 6

.

.

.

Instead of :

adcValue[0]=Channel 0

adcValue[1]=Channel 1

adcValue[2]=Channel 2

adcValue[3]=Channel 3

.

.

.

If I put 96 cylces or higher everything OK.

I don't have any overun because I configure CR2->DELS to ADC_AUTOWAIT_UNTIL_DATA_READ and I also check that ErrorCallback is never call.

I use CubeMX to generate base code (STM32 HAL lib), here is ADC init :

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.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
  hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
  hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.NbrOfConversion = 14;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
 
  MODIFY_REG(ADC1->CR2,ADC_CR2_DELS_Msk,ADC_AUTOWAIT_UNTIL_DATA_READ);
 
  sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES;
 
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = 1;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = 2;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = 3;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_18;
  sConfig.Rank = 4;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = 5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = 6;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = 7;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_7;
  sConfig.Rank = 8;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_19;
  sConfig.Rank = 9;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_20;
  sConfig.Rank = 10;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_9;
  sConfig.Rank = 11;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_21;
  sConfig.Rank = 12;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = 13;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) {
    Error_Handler();
  }
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = 14;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK){
    Error_Handler();
  }
 
}

Here is interrupt management :

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
 
	adcValue[adcChannel]=HAL_ADC_GetValue(hadc);
	if(adcChannel == (NUMBER_OF_ADC_CHANNEL-1)){
		adcChannel = 0;
		adcConvCplt = true;
	}
	else{
		adcChannel++;
	}
 
}

Does any one have an idea ?

Best regards

3 REPLIES 3

>>Does any one have an idea ?

Use DMA not interrupts

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
MAlle.17
Associate

Yes it's a solution.

Put 96 cycles for sampling time or change to pooling are others solutions.

My question is more why I have this behaviour instead of how to patch something that I don't understand.

Anyway thank you for the answer.

JLojo
Associate III

Hello,

I do have the exact same problem!

Actually, I had a project running on a STM32 L412.

Due to the current component shortage, I only found STM32 L151 available, with basically the same pinout.

I thus adapted my project (which is very similar to what described MAlle.17) for running on the L151 and get the exact same behavior.

I fought for hours trying to find the right compromise between sampling rate, sampling time, clock division and others, but unsuccessful.

I'm about to switch to DMA mode, but since this will be rather complex to manage it across the different stm32, I wanted to know if there is nothing obvious that I've not been able to see allowing me to do it simply...

Thanks for any suggestion/advice

JYL