ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

获取STM32系列APB1/APB2/HCLK/SYSCLK系统时钟频率使用J-Link-RTT打印

2020-03-14 09:36:42  阅读:644  来源: 互联网

标签:tmp Clocks clock CFGR SYSCLK STM32 Frequency APB2 RCC


获取STM3F10x系列系统各时钟频率

在STM32F10x系列库函数stm32f10x_rcc.c中有函数void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)用来获取系统APB1、APB2、HCLK、SYSCLK等频率。

一、获取系统各时钟频率

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);
	}
}

二、时钟频率显示结果

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

在这里插入图片描述
在这里插入图片描述注意:
1. RCC_GetSYSCLKSource()获取系统时钟源的来源。
0x00 : HSI used as system clock
0x04 : HSE used as system clock
0x08 : PLL used as system clock
2. 本次使用STM32F103R8T6芯片。
3. 我的板子无外部晶振,而是通过内部高速振荡器(HSI)倍频得到系统时钟频率,因此最大频率只能倍频到64MHZ。

三、RCC_GetSYSCLKSource()源码

/**
* @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));
}

四、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;
}

标签:tmp,Clocks,clock,CFGR,SYSCLK,STM32,Frequency,APB2,RCC
来源: https://blog.csdn.net/Ceosat/article/details/104845967

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有