Skip to main content
halbeeee
Associate II
March 23, 2023
Solved

Change ADC clock in STM32H7

Hello, i'm using an STM32H7 but unfortunately for a known bug of the firmware package i'm not able to select the ADC prescaler. Uprading to a newer firmware package is not considered.

At the moment i resolved applying a prescaler with the line

hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;

The problem is that this only works with the synchronous clock, if i try the asynchronous clock the ADC doesn't work, like if the clock is not enabled.

0693W00000aJYovQAG.pngMy idea is that i have to enable PLL2P because is disabled, how can i do it with code since i'm not able to manage it througth cube ide?

Thank you in advice

This topic has been closed for replies.
LCE
LCEBest answer
Principal III
March 23, 2023

Find SystemClock_Config() and modify.

Here's some clock setup for a Nucleo H723, including ADC from PLL3:

But better check the values for your application.

/**
 * @brief System Clock Configuration
 * @retval None
 */
/* notes:
 *	Power:
 *		- voltage scaling for core:
 *			VOS0 ~1.36 V - "boosted performance" - highest freq -> highest power
 *			VOS1 ~1.21 V - "high performance"
 *			VOS2 ~1.10 V - "medium performance"
 *		-> in these voltage ranges SAI, I2S, OctoSPI can work with at least up to
 *			113 MHz (RM0468, pg 336)
 *
 *	PLLs:
 *		- main PLL input range: 2 .. 16 MHz
 *		- PLL2 & 3 input range: 1 .. 2 MHz
 */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
	RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
 
	/* supply configuration update enable */
	HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
 
	/* configure the main internal regulator output voltage */
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
	while( 0 == __HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) );
 
	/* configure LSE Drive Capability */
	HAL_PWR_EnableBkUpAccess();
	__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
 
	/* Macro to configure the PLL clock source */
	__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
 
 
	/* initialize RCC oscillators and PLL 1 for core and peripheral busses
	 */
	RCC_OscInitStruct.OscillatorType 	= RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSE;
	RCC_OscInitStruct.HSEState 			= RCC_HSE_BYPASS;
	RCC_OscInitStruct.LSEState 			= RCC_LSE_ON;
	RCC_OscInitStruct.PLL.PLLState 		= RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource 	= RCC_PLLSOURCE_HSE;
 
/* NUCLEO_H723: 8.333 MHz input from ST-LINK */
	RCC_OscInitStruct.PLL.PLLM 			= 4;	/* -> 8 MHz / 4 = 2 MHz */
	RCC_OscInitStruct.PLL.PLLN 			= 192;	/* -> 400 MHz */
	RCC_OscInitStruct.PLL.PLLP 			= 1;		/* 400 MHz */
	RCC_OscInitStruct.PLL.PLLQ 			= 5;		/* 80 MHz for FDCAN */
	RCC_OscInitStruct.PLL.PLLR 			= 4;		/* 100 MHz */
	RCC_OscInitStruct.PLL.PLLRGE 		= RCC_PLL1VCIRANGE_1;
	RCC_OscInitStruct.PLL.PLLVCOSEL 	= RCC_PLL1VCOWIDE;
	RCC_OscInitStruct.PLL.PLLFRACN 		= 0;
 
	if( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK ) Error_Handler();
 
	/** Initializes the CPU, AHB and APB buses clocks
	*/
	RCC_ClkInitStruct.ClockType 		= RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
											| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2
											| RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
	RCC_ClkInitStruct.SYSCLKSource 		= RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.SYSCLKDivider 	= RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.AHBCLKDivider 	= RCC_HCLK_DIV2;
	RCC_ClkInitStruct.APB1CLKDivider 	= RCC_APB1_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider 	= RCC_APB2_DIV2;
	RCC_ClkInitStruct.APB3CLKDivider 	= RCC_APB3_DIV2;
	RCC_ClkInitStruct.APB4CLKDivider 	= RCC_APB4_DIV2;
 
	if( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK ) Error_Handler();
}
 
/**
 * @brief Peripherals Common Clock Configuration
 * @retval None
 */
void PeriphCommonClock_Config(void)
{
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
 
/* NUCLEO_H723: 8.333 MHz input from ST-LINK */
 
/* PLL2: base for 400 kHz / x sampling rate */
	PeriphClkInitStruct.PLL2.PLL2M 		= 2;
	PeriphClkInitStruct.PLL2.PLL2N 		= 122;
	PeriphClkInitStruct.PLL2.PLL2P 		= 5;	/* 102.4 MHz */
	PeriphClkInitStruct.PLL2.PLL2Q 		= 5;	/* 102.4 MHz */
	PeriphClkInitStruct.PLL2.PLL2R 		= 10;	/* 51.2 MHz */
	PeriphClkInitStruct.PLL2.PLL2RGE 	= RCC_PLL2VCIRANGE_2;
	PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
	PeriphClkInitStruct.PLL2.PLL2FRACN 	= PLL_FRACN_BASE_8M3_51M2;
 
/* PLL3: base for 192 kHz / x sampling rate */
	PeriphClkInitStruct.PLL3.PLL3M 		= 5;
	PeriphClkInitStruct.PLL3.PLL3N 		= 235;
	PeriphClkInitStruct.PLL3.PLL3P 		= 4;	/* 98.304 MHz */
	PeriphClkInitStruct.PLL3.PLL3Q 		= 4;	/* 98.304 MHz */
	PeriphClkInitStruct.PLL3.PLL3R 		= 8;	/* 49.152 MHz */
	PeriphClkInitStruct.PLL3.PLL3RGE 	= RCC_PLL3VCIRANGE_0;
	PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOMEDIUM;
	PeriphClkInitStruct.PLL3.PLL3FRACN 	= PLL_FRACN_BASE_8M3_98M3;
 
/* SAI 1, SAI 4 */
	PeriphClkInitStruct.PeriphClockSelection |= ( RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI4A | RCC_PERIPHCLK_SAI4B );
/* SPI 1, SPI 2, SPI 6 */
	PeriphClkInitStruct.PeriphClockSelection |= ( RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | RCC_PERIPHCLK_SPI6 );
 
	PeriphClkInitStruct.Sai1ClockSelection 		= RCC_SAI1CLKSOURCE_PLL2;
	PeriphClkInitStruct.Sai4AClockSelection 	= RCC_SAI4ACLKSOURCE_PLL2;
	PeriphClkInitStruct.Spi123ClockSelection 	= RCC_SPI123CLKSOURCE_PLL2;
	PeriphClkInitStruct.Spi6ClockSelection 		= RCC_SPI6CLKSOURCE_PLL2;
 
/* ADC */
	PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_ADC;
	PeriphClkInitStruct.AdcClockSelection 	 = RCC_ADCCLKSOURCE_PLL3;
 
	if( HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK ) Error_Handler();
}

4 replies

LCE
LCEBest answer
Principal III
March 23, 2023

Find SystemClock_Config() and modify.

Here's some clock setup for a Nucleo H723, including ADC from PLL3:

But better check the values for your application.

/**
 * @brief System Clock Configuration
 * @retval None
 */
/* notes:
 *	Power:
 *		- voltage scaling for core:
 *			VOS0 ~1.36 V - "boosted performance" - highest freq -> highest power
 *			VOS1 ~1.21 V - "high performance"
 *			VOS2 ~1.10 V - "medium performance"
 *		-> in these voltage ranges SAI, I2S, OctoSPI can work with at least up to
 *			113 MHz (RM0468, pg 336)
 *
 *	PLLs:
 *		- main PLL input range: 2 .. 16 MHz
 *		- PLL2 & 3 input range: 1 .. 2 MHz
 */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
	RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
 
	/* supply configuration update enable */
	HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
 
	/* configure the main internal regulator output voltage */
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
	while( 0 == __HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY) );
 
	/* configure LSE Drive Capability */
	HAL_PWR_EnableBkUpAccess();
	__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
 
	/* Macro to configure the PLL clock source */
	__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
 
 
	/* initialize RCC oscillators and PLL 1 for core and peripheral busses
	 */
	RCC_OscInitStruct.OscillatorType 	= RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSE;
	RCC_OscInitStruct.HSEState 			= RCC_HSE_BYPASS;
	RCC_OscInitStruct.LSEState 			= RCC_LSE_ON;
	RCC_OscInitStruct.PLL.PLLState 		= RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource 	= RCC_PLLSOURCE_HSE;
 
/* NUCLEO_H723: 8.333 MHz input from ST-LINK */
	RCC_OscInitStruct.PLL.PLLM 			= 4;	/* -> 8 MHz / 4 = 2 MHz */
	RCC_OscInitStruct.PLL.PLLN 			= 192;	/* -> 400 MHz */
	RCC_OscInitStruct.PLL.PLLP 			= 1;		/* 400 MHz */
	RCC_OscInitStruct.PLL.PLLQ 			= 5;		/* 80 MHz for FDCAN */
	RCC_OscInitStruct.PLL.PLLR 			= 4;		/* 100 MHz */
	RCC_OscInitStruct.PLL.PLLRGE 		= RCC_PLL1VCIRANGE_1;
	RCC_OscInitStruct.PLL.PLLVCOSEL 	= RCC_PLL1VCOWIDE;
	RCC_OscInitStruct.PLL.PLLFRACN 		= 0;
 
	if( HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK ) Error_Handler();
 
	/** Initializes the CPU, AHB and APB buses clocks
	*/
	RCC_ClkInitStruct.ClockType 		= RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
											| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2
											| RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1;
	RCC_ClkInitStruct.SYSCLKSource 		= RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.SYSCLKDivider 	= RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.AHBCLKDivider 	= RCC_HCLK_DIV2;
	RCC_ClkInitStruct.APB1CLKDivider 	= RCC_APB1_DIV2;
	RCC_ClkInitStruct.APB2CLKDivider 	= RCC_APB2_DIV2;
	RCC_ClkInitStruct.APB3CLKDivider 	= RCC_APB3_DIV2;
	RCC_ClkInitStruct.APB4CLKDivider 	= RCC_APB4_DIV2;
 
	if( HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK ) Error_Handler();
}
 
/**
 * @brief Peripherals Common Clock Configuration
 * @retval None
 */
void PeriphCommonClock_Config(void)
{
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 };
 
/* NUCLEO_H723: 8.333 MHz input from ST-LINK */
 
/* PLL2: base for 400 kHz / x sampling rate */
	PeriphClkInitStruct.PLL2.PLL2M 		= 2;
	PeriphClkInitStruct.PLL2.PLL2N 		= 122;
	PeriphClkInitStruct.PLL2.PLL2P 		= 5;	/* 102.4 MHz */
	PeriphClkInitStruct.PLL2.PLL2Q 		= 5;	/* 102.4 MHz */
	PeriphClkInitStruct.PLL2.PLL2R 		= 10;	/* 51.2 MHz */
	PeriphClkInitStruct.PLL2.PLL2RGE 	= RCC_PLL2VCIRANGE_2;
	PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
	PeriphClkInitStruct.PLL2.PLL2FRACN 	= PLL_FRACN_BASE_8M3_51M2;
 
/* PLL3: base for 192 kHz / x sampling rate */
	PeriphClkInitStruct.PLL3.PLL3M 		= 5;
	PeriphClkInitStruct.PLL3.PLL3N 		= 235;
	PeriphClkInitStruct.PLL3.PLL3P 		= 4;	/* 98.304 MHz */
	PeriphClkInitStruct.PLL3.PLL3Q 		= 4;	/* 98.304 MHz */
	PeriphClkInitStruct.PLL3.PLL3R 		= 8;	/* 49.152 MHz */
	PeriphClkInitStruct.PLL3.PLL3RGE 	= RCC_PLL3VCIRANGE_0;
	PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOMEDIUM;
	PeriphClkInitStruct.PLL3.PLL3FRACN 	= PLL_FRACN_BASE_8M3_98M3;
 
/* SAI 1, SAI 4 */
	PeriphClkInitStruct.PeriphClockSelection |= ( RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI4A | RCC_PERIPHCLK_SAI4B );
/* SPI 1, SPI 2, SPI 6 */
	PeriphClkInitStruct.PeriphClockSelection |= ( RCC_PERIPHCLK_SPI1 | RCC_PERIPHCLK_SPI2 | RCC_PERIPHCLK_SPI6 );
 
	PeriphClkInitStruct.Sai1ClockSelection 		= RCC_SAI1CLKSOURCE_PLL2;
	PeriphClkInitStruct.Sai4AClockSelection 	= RCC_SAI4ACLKSOURCE_PLL2;
	PeriphClkInitStruct.Spi123ClockSelection 	= RCC_SPI123CLKSOURCE_PLL2;
	PeriphClkInitStruct.Spi6ClockSelection 		= RCC_SPI6CLKSOURCE_PLL2;
 
/* ADC */
	PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_ADC;
	PeriphClkInitStruct.AdcClockSelection 	 = RCC_ADCCLKSOURCE_PLL3;
 
	if( HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK ) Error_Handler();
}

halbeeee
halbeeeeAuthor
Associate II
March 23, 2023

Thank for your answer, very useful. The only question is that you told me to modify the SystemClock_Config(), but looking on your code seems like that the function that i need to modify is PeriphCommonClock_Config(), which i don't have. Is there a way to make it appear or do i need to write by hand and then call it?

LCE
Principal III
March 23, 2023

Oops... okay, it's in RCC_PeriphCLKInitTypeDef ()

However you like, it's no big deal to integrate that into SystemClock_Config().

halbeeee
halbeeeeAuthor
Associate II
March 23, 2023

[]