2020-01-16 07:24 PM
According to the spec, it says the ADC clock frequency is up to 60Mhz for a single channel. Does it mean we cannot apply the ADC clock more than 60Mhz to the ADC modules? But in the STM32Cube example code, the ADC clock applied to the ADC module is set to higher than 60Mhz. I don't know which one I should trust. Thanks .
2020-01-16 11:50 PM
Datasheet (DS) /reference manual (RM) are the authoritative information source, not any "library". Also, always read the Errata for the given chip, too.
This said, sometimes datasheets may contain bugs, but in this case I'd say the given value is solid.
> But in the STM32Cube example code, the ADC clock applied to the ADC module is set to higher than 60Mhz.
Where?
And where is the above displayed Table1 from? It's not the DS either.
JW
2020-01-17 01:12 AM
Hi JW,
Thanks for the assitant. The above table is cut from an application note called "STM32G4 ADC use tips and recommendations". You can find the application note from the link, https://www.st.com/content/st_com/en/products/microcontrollers-microprocessors/stm32-32-bit-arm-cortex-mcus/stm32-mainstream-mcus/stm32g4-series/stm32g4x4/stm32g474re.html#resource.
Here is the example code snippet. The system clock is set to 150Mhz and is selected as the clock source of ADC. The ADC clock is then divided by 2 (150Mhz/2 = 75Mhz). It looks like the ADC can operate at the frequency higher than 60Mhz and no limitation. Thanks.
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4;
RCC_OscInitStruct.PLL.PLLN = 75;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
{
Error_Handler();
}
/** Initializes the peripherals clocks
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC12;
PeriphClkInit.Adc12ClockSelection = RCC_ADC12CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief ADC1 Initialization Function
* @param 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_AnalogWDGConfTypeDef AnalogWDGConfig = {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_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.GainCompensation = 0;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
2020-01-17 02:16 AM
The limit is given probably not by the digital part of ADC but the analog. Ie. from programmer point of view it will work, but precision may be compromised.
Is this code part of some example in Cube?
JW
2020-01-17 01:50 PM
I did the same question when the G4 was released.
Comparing STM32G4 ADC with others families, using asynchronous clock mode to avoid timer trigger uncertainty.
STM32F3 ADC clock = 72MHZ, Sampling time 20.8nS.
STM32L4 ADC clock = 80 MHZ, Sampling time 31.25nS.
STM32L5 ADC clock = 80 MHZ, Sampling time = 31.25nS.
STM32G4 ADC clock = 170MHZ/4 = 42.5MHZ, Sampling time = 58.8 nS.
Or:
STM32G4 ADC clock = 104MHZ/2 = 52MHZ, Sampling time = 48 nS. (Reducing CPU clock to only 104 MHZ)
I don't think ST initially specified STM32G4 ADC to be inferior to the F3, L4 and L5 ADCs.
I think the examples of STM32CubeMX were made based on an initial specification where the ADC clock was 75 MHZ. After the tests, ST found that it could not exceed 60MHZ for a single ADC and 52MHZ for multiples ADCs, but did not change the examples. I think the limitation on the ADC clock was an errata that became a specification.
ST should report the consequence of overclock de ADC to 75 MHZ. Maybe the limitation of 52MHZ is for a condition of all ADCs are in the continuous conversion mode.