2024-09-30 11:38 PM - last edited on 2024-10-01 04:11 AM by Andrew Neil
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
}
}
2024-09-30 11:50 PM - edited 2024-10-01 02:23 AM
Hello @giwonKIM ,
Please use </> button to paste your code. I modify your post then ..
Thank you for your understanding
2024-10-01 06:01 AM
> 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.