Bootstrap

STM32学习——RCC时钟配置

使用固件库进行的RCC时钟配置。

时钟树:

由时钟配置寄存器 CFGR 的位 17:PLLXTPRE使能HSE为8M  -->  时钟配置寄存器CFGR的位16: PLLSRC 将HSE(8M)选为PLL(锁相环)的输入  -->  CFGR位 21-18:PLLMUL[3:0]倍频因子选择9M得到PLLCLK(64M)  --> CFGR 的位1-0:SW[1:0] 设置SYSTCLK选择PLLCLK作为系统时钟(72M)  -->  在系统时钟的基础上配置三条总线的时钟(1.AHB、2.APB2、3.APB1)  -->  AHB等于系统时钟的1分频(72M) ,HCLK等于72M  -->  在HCLK基础上1分频得到APB2(72M)  -->  在HCLK基础上2分频得到APB1(36M)

 

程序编写流程:

使能HSE(RCC_HSEConfig) --> 等待HSE稳定(RCC_WaitForHSEStartUp) --> HSE稳定后使能预取指(FLASH_PrefetchBufferCmd) --> 设置FLASH等待(FLASH_SetLatency) --> 设置三总线分频因子(RCC_HCLKConfig、RCC_PCLK1Config、RCC_PCLK2Config) --> 设置PLL锁相环的时钟源和倍频因子(RCC_PLLConfig) --> 使能PLL --> 等待PLL稳定 while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET ); --> 选择系统时钟(RCC_SYSCLKConfig) --> 等待系统时钟稳定while( RCC_GetSYSCLKSource() != 0x08 );

#include "clkconfig.h"

void HSEConfig(uint32_t RCC_PLLMul_x)
{
	ErrorStatus HSEStatus;
	
	//将RCC寄存器复位为复位值
	RCC_DeInit();
	
	//使能HSE
	RCC_HSEConfig( RCC_HSE_ON );
	
	HSEStatus = RCC_WaitForHSEStartUp();
	
	if( HSEStatus == SUCCESS )
	{
		//使能预取指
		FLASH_PrefetchBufferCmd( FLASH_PrefetchBuffer_Enable );
		//设置等待
		FLASH_SetLatency( FLASH_Latency_2 );
		
		//配置三总线分频因子
		RCC_HCLKConfig( RCC_SYSCLK_Div1 );
		RCC_PCLK1Config( RCC_HCLK_Div2 );
		RCC_PCLK2Config( RCC_HCLK_Div1 );
		
		//配置PLL的时钟源和倍频因子
		RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_x );
		
		//使能PLL
		RCC_PLLCmd(ENABLE);
		
		//等待PLL稳定
		while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY ) == RESET );
		
		//选择系统时钟
		RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );
		
		//等待系统时钟稳定
		while( RCC_GetSYSCLKSource() != 0x08 );
	}
	else
	{
		/* HSE启动失败 */
	}
}

为什么要配置FLASH ? 

  • 取指令时,两条指令之间需要时间间隔,所以需要使能预取指,设置时延,72M的频率需要两个等待状态;

为什么程序编写流程跟时钟树流程不一样?

  • 选择时钟源后,分频因子不可轻易改动,需要先配置好分频因子,再配置时钟源;

总结:

使用固件库编程给我的感觉像是用积木搭房子,每块积木有各自的作用,合理的组合可以实现一定的功能,但需要事先了解步骤,任然需要对寄存器的有一定的了解。

;