Obtain clock frequency of STM32 series APB1/APB2/HCLK/SYSCLK system and print with J-Link-RTT

In STM32F10x series library function, there is the function void RCC ﹣ getclocksfreq (RCC ﹣ clockstdef * RCC ﹣ clocks) to obtain the frequency of system APB1, APB2, HCLK, SYSCLK, etc.

1, Obtain the clock frequency of the system

RCC_ClocksTypeDef RCC_CLK;
int main(void)
{	
	vSystem_Init();
	
	RCC_GetClocksFreq(&RCC_CLK);//Get chip frequencies
	#if ( USE_SEGGER_RTT_ENABLE > 0 )//Use segger rtt enable
	SEGGER_RTT_printf(0, "System Clock Source : %d\r\n", RCC_GetSYSCLKSource());
	SEGGER_RTT_printf(0, "APB1/PCLK1 : %dHZ\r\n", RCC_CLK.PCLK1_Frequency);
	SEGGER_RTT_printf(0, "APB2/PCLK2 : %dHZ\r\n", RCC_CLK.PCLK2_Frequency);
	SEGGER_RTT_printf(0, "SYSCLK     : %dHZ\r\n", RCC_CLK.SYSCLK_Frequency);
	SEGGER_RTT_printf(0, "HCLK       : %dHZ\r\n", RCC_CLK.HCLK_Frequency);
	#endif

	while(1)
	{
		vKeyBoard_Service_Handle();
		PAout(6) = 0;
		vDelay_ms(100);
		PAout(6) = 1;
		vDelay_ms(1000);
	}
}

2, Clock frequency display result

00> Build Times: Mar 14 2020  08:57:46
00> STM32F103xx  Start Running......
00> 
00> System Clock Source  : 8
00> APB1/PCLK1Â : 64000000HZ
00> APB2/PCLK2Â : 64000000HZ
00> SYSCLK      : 64000000HZ
00> HCLK        : 64000000HZ


Be careful:
1. RCC_GetSYSCLKSource() gets the source of the system clock source.
0x00 : HSI used as system clock
0x04 : HSE used as system clock
0x08 : PLL used as system clock
2. STM32F103R8T6 chip is used this time.
3. My board has no external crystal oscillator, but the system clock frequency is obtained by multiplying the internal high-speed oscillator (HSI), so the maximum frequency can only be doubled to 64MHZ.

3, RCC ﹐ getsysclksource() source code

/**
* @brief  Returns the clock source used as system clock.
* @param  None
* @retval The clock source used as system clock. The returned value can
*   be one of the following:
*     - 0x00: HSI used as system clock
*     - 0x04: HSE used as system clock
*     - 0x08: PLL used as system clock
*/
uint8_t RCC_GetSYSCLKSource(void)
{
	return ((uint8_t)(RCC->CFGR & CFGR_SWS_Mask));
}

4, Source code of RCC ﹐ getclocksfreq()

/**
* @brief  Returns the frequencies of different on chip clocks.
* @param  RCC_Clocks: pointer to a RCC_ClocksTypeDef structure which will hold
*         the clocks frequencies.
* @note   The result of this function could be not correct when using 
*         fractional value for HSE crystal.  
* @retval None
*/
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
	uint32_t tmp = 0, pllmull = 0, pllsource = 0, presc = 0;

	#ifdef  STM32F10X_CL
	uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
	#endif /* STM32F10X_CL */

	#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
	uint32_t prediv1factor = 0;
	#endif

	/* Get SYSCLK source -------------------------------------------------------*/
	tmp = RCC->CFGR & CFGR_SWS_Mask;

	switch (tmp)
	{
		case 0x00:  /* HSI used as system clock */
			RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
		break;
		
		case 0x04:  /* HSE used as system clock */
			RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
		break;
		
		case 0x08:  /* PLL used as system clock */
			/* Get PLL clock source and multiplication factor ----------------------*/
			pllmull = RCC->CFGR & CFGR_PLLMull_Mask;
			pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;

			#ifndef STM32F10X_CL      
			pllmull = ( pllmull >> 18) + 2;
			if (pllsource == 0x00)
			{/* HSI oscillator clock divided by 2 selected as PLL clock entry */
				RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
			}
			else
			{
				#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
				prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;
				/* HSE oscillator clock selected as PREDIV1 clock entry */
				RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull; 
				#else
				/* HSE selected as PLL clock entry */
				if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (uint32_t)RESET)
				{/* HSE oscillator clock divided by 2 */
					RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE >> 1) * pllmull;
				}
				else
				{
					RCC_Clocks->SYSCLK_Frequency = HSE_VALUE * pllmull;
				}
				#endif
			}
			#else
			pllmull = pllmull >> 18;

			if (pllmull != 0x0D)
			{
				pllmull += 2;
			}
			else
			{ /* PLL multiplication factor = PLL input clock * 6.5 */
				pllmull = 13 / 2; 
			}

			if (pllsource == 0x00)
			{/* HSI oscillator clock divided by 2 selected as PLL clock entry */
				RCC_Clocks->SYSCLK_Frequency = (HSI_VALUE >> 1) * pllmull;
			}
			else
			{/* PREDIV1 selected as PLL clock entry */
				/* Get PREDIV1 clock source and division factor */
				prediv1source = RCC->CFGR2 & CFGR2_PREDIV1SRC;
				prediv1factor = (RCC->CFGR2 & CFGR2_PREDIV1) + 1;

				if (prediv1source == 0)
				{ /* HSE oscillator clock selected as PREDIV1 clock entry */
					RCC_Clocks->SYSCLK_Frequency = (HSE_VALUE / prediv1factor) * pllmull;          
				}
				else
				{/* PLL2 clock selected as PREDIV1 clock entry */
					/* Get PREDIV2 division factor and PLL2 multiplication factor */
					prediv2factor = ((RCC->CFGR2 & CFGR2_PREDIV2) >> 4) + 1;
					pll2mull = ((RCC->CFGR2 & CFGR2_PLL2MUL) >> 8 ) + 2; 
					RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                         
				}
			}
			#endif /* STM32F10X_CL */ 
		break;

		default:
		RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
		break;
	}

	/* Compute HCLK, PCLK1, PCLK2 and ADCCLK clocks frequencies ----------------*/
	/* Get HCLK prescaler */
	tmp = RCC->CFGR & CFGR_HPRE_Set_Mask;
	tmp = tmp >> 4;
	presc = APBAHBPrescTable[tmp];
	/* HCLK clock frequency */
	RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;
	/* Get PCLK1 prescaler */
	tmp = RCC->CFGR & CFGR_PPRE1_Set_Mask;
	tmp = tmp >> 8;
	presc = APBAHBPrescTable[tmp];
	/* PCLK1 clock frequency */
	RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
	/* Get PCLK2 prescaler */
	tmp = RCC->CFGR & CFGR_PPRE2_Set_Mask;
	tmp = tmp >> 11;
	presc = APBAHBPrescTable[tmp];
	/* PCLK2 clock frequency */
	RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
	/* Get ADCCLK prescaler */
	tmp = RCC->CFGR & CFGR_ADCPRE_Set_Mask;
	tmp = tmp >> 14;
	presc = ADCPrescTable[tmp];
	/* ADCCLK clock frequency */
	RCC_Clocks->ADCCLK_Frequency = RCC_Clocks->PCLK2_Frequency / presc;
}
Published 7 original articles, won praise 4, visited 162
Private letter follow

Posted by Koobazaur on Sat, 14 Mar 2020 07:40:30 -0700