cancel
Showing results for 
Search instead for 
Did you mean: 

Multi ADC in parallel

giwonKIM
Associate III

Hi I'm using STM32H743ZG.

I am currently using all three ADCs.

Each ADC initialization code:

 

#ifdef CHANNEL1
/**
  * @brief ADC1 Initialization Function
  *  None
  * @retval None
  */
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_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = ENABLE;
  hadc1.Init.Oversampling.Ratio = 40;
  hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_NONE;
  hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  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_2;
  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(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}
#endif
#ifdef CHANNEL2
/**
  * @brief ADC2 Initialization Function
  *  None
  * @retval None
  */
static void MX_ADC2_Init(void)
{

  /* USER CODE BEGIN ADC2_Init 0 */

  /* USER CODE END ADC2_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC2_Init 1 */

  /* USER CODE END ADC2_Init 1 */

  /** Common config
  */
  hadc2.Instance = ADC2;
  hadc2.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc2.Init.Resolution = ADC_RESOLUTION_12B;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc2.Init.LowPowerAutoWait = DISABLE;
  hadc2.Init.ContinuousConvMode = DISABLE;
  hadc2.Init.NbrOfConversion = 1;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc2.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc2.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc2.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc2.Init.OversamplingMode = ENABLE;
  hadc2.Init.Oversampling.Ratio = 40;
  hadc2.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_NONE;
  hadc2.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc2.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  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(&hadc2, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC2_Init 2 */

  /* USER CODE END ADC2_Init 2 */

}
#endif
#ifdef CHANNEL3
/**
  * @brief ADC3 Initialization Function
  *  None
  * @retval None
  */
static void MX_ADC3_Init(void)
{

  /* USER CODE BEGIN ADC3_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
  /* USER CODE END ADC3_Init 0 */

  /* USER CODE BEGIN ADC3_Init 1 */

  /* USER CODE END ADC3_Init 1 */

  /** Common config
  */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc3.Init.Resolution = ADC_RESOLUTION_12B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = DISABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc3.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = ENABLE;
  hadc3.Init.Oversampling.Ratio = 40;
  hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_NONE;
  hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc3.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC3_Init 2 */
  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();
  }
  /* USER CODE END ADC3_Init 2 */

}
#endif 

 

It takes about 8usec to operate one ADC. However, if you operate more than two, it takes about 10usec per one. Is this because we share the same CLOCK?

I want all ADCs to operate with around 8usec time. If there's a way, please let me know.

Here is my code:

 

/**
  * @brief  PWM Pulse finished callback in non-blocking mode
  *   htim TIM handle
  * @retval None
  */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
if((htim->Instance == TIM5) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1))
{
//internal(mcu) adc start(external input mode)
#ifdef CHANNEL1

HAL_ADC_Start_IT(&hadc1);
HAL_GPIO_WritePin(DEBUG_IADC1_GPIO_Port, DEBUG_IADC1_Pin, GPIO_PIN_SET); //TP7
#endif
#ifdef CHANNEL2

HAL_ADC_Start_IT(&hadc2);
//HAL_GPIO_WritePin(DEBUG_IADC2_GPIO_Port, DEBUG_IADC2_Pin, GPIO_PIN_SET);
#endif
#ifdef CHANNEL3
HAL_ADC_Start_IT(&hadc3);
HAL_GPIO_WritePin(DEBUG_IADC3_GPIO_Port, DEBUG_IADC3_Pin, GPIO_PIN_SET);
#endif

//external adc(ad4003) read start
ADCRead();

}
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
#ifdef CHANNEL1
//internal adc1 finish
if(hadc->Instance == ADC1)
{
HAL_GPIO_WritePin(DEBUG_IADC1_GPIO_Port, DEBUG_IADC1_Pin, GPIO_PIN_RESET);
IntAdc1Value = HAL_ADC_GetValue(&hadc1);
IsADC1Finished = TRUE;
}
#endif

#ifdef CHANNEL2
//internal adc2 finish
if(hadc->Instance == ADC2)
{
//HAL_GPIO_WritePin(DEBUG_IADC2_GPIO_Port, DEBUG_IADC2_Pin, GPIO_PIN_RESET);
IntAdc2Value = HAL_ADC_GetValue(&hadc2);
IsADC2Finished = TRUE;
}
#endif

#ifdef CHANNEL3
//internal adc3 finish
if(hadc->Instance == ADC3)
{
HAL_GPIO_WritePin(DEBUG_IADC3_GPIO_Port, DEBUG_IADC3_Pin, GPIO_PIN_RESET);
IntAdc3Value = HAL_ADC_GetValue(&hadc3);
IsADC3Finished = TRUE;
}
#endif

//all internal adc finish
if(IsADC1Finished == TRUE && IsADC2Finished == TRUE && IsADC3Finished == TRUE)
{
#ifdef CHANNEL1
//periodic_func1();
IsADC1Finished = FALSE;
#endif
#ifdef CHANNEL2
//periodic_func2();
IsADC2Finished = FALSE;
#endif
#ifdef CHANNEL3
//periodic_func3();
IsADC3Finished = FALSE;
#endif
}
}

 

 
If you have any question, please ask me.
2 REPLIES 2
SofLit
ST Employee

Hello @giwonKIM ,

Please use </> button to paste your code. I modify your post then ..

Thank you for your understanding

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
TDK
Guru

> HAL_ADC_Start_IT

The increase in time is probably due to the time it takes for your code to execute between each sample. Use DMA if you want to convert ADC channels at high speed.

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