cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 Using of Multichannel ADC Triggered by Timer in Interrupt Mode

Ey.1
Associate II

I'm having a trouble when using multichannel ADC. In my application there is 2 ADC which contains 7 channels. In ADC Interrupt Callback, I'm pushing the read data to array of 7 elements. But I couldn't see the proper value in proper element of array, they are sliding in the array countinously.

Each ADC contain seven ACS725. So there is no High-Z situation. I'm seeing at the pins 0.5V constant (zero current) . My callback and init part is in above. Thanks a lot for your help!

/* ADC3 init function */
void MX_ADC3_Init(void)
{
  ADC_ChannelConfTypeDef sConfig = {0};
 
  /** Common config
  */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.NbrOfConversion = 7;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T15_TRGO;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_7;
  sConfig.Rank = ADC_REGULAR_RANK_6;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = ADC_REGULAR_RANK_7;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
 
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	if(__HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC))
	{
		g_internalAdc1.m_rawResultArray[cntAcs1++] =  (uint16_t) HAL_ADC_GetValue(hadc);
 
		if(cntAcs1 == g_internalAdc1.MS_NUMBER_OF_CHANNEL)
		{
			cntAcs1 = 0;
			g_internalAdc1Ready = true;
		}
	}
 
	if(__HAL_ADC_GET_FLAG(&hadc3, ADC_FLAG_EOC))
	{
		g_internalAdc2.m_rawResultArray[cntAcs2++] = (uint16_t) HAL_ADC_GetValue(hadc);
 
		if(cntAcs2 == g_internalAdc2.MS_NUMBER_OF_CHANNEL)
		{
			cntAcs2 = 0;
			g_internalAdc2Ready = true;
		}
	}
}

In SystemClock_Config function:

PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL3; //129Mhz (  (I also tried other options)

My timer also adjusted to 40ms period.

In debug, what I mean results are sliding in the array :

0693W000007Z7HqQAK.png 

0693W000007Z7IFQA0.png 

etc...

(while ~7000 raw data is zero current, ~14000 is equalt to 1.2 Amper. I'm applying the 1.2A to only one channel that has to be in the 3rd element of the array)

After I tried with a new project with applying same configurations with using only 2 channel: I aware that there is only 1 conversion result. The other result does not seen on the callback and also DR register. And when I start the ADC with software(without timer trig) it looks like it takes the result from random channel. I could not solve problem for three days.

Thanks again.

4 REPLIES 4

Hello

ADC1 and ADC3 have different IRQ handlers and different NVIC priorities (one interrupts the other)

Inside completion_callback dont check for eof flag.

Check the handle

if(hadc==&hadc1) {;}

else if (hadc==&hadc3)

else{;} //whatelse

The Fadc is about 32Mhz .Is BOOST bit(s) set? (boost functionality differentiates with chip revision Y or V)

0693W000007Z8hpQAC.jpg 

0693W000007Z8qwQAC.jpg

Thanks for reply! I changed the conditions in callback like you say. I was not aware of boost mode, it was on reset state. My chip is V revision, and I set the these two bits and I also observe in SFRs they changed to true state. But there is no timing differences.

Ey.1
Associate II

When in continuous mode, disabling the timer trigger, values always sliding in the array :(

Ey.1
Associate II

In DMA mode, disabling adc global interrupt, it is working in a true way. But in interrupt mode, I could not handle.