STM32时钟 下面是一个STM32时钟框图: STM32时钟系统 在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz STM32时钟配置手动配置使用HSE时钟,程序设置时钟参数流程:
1、将RCC寄存器重新设置为默认值 RCC_DeInit;
2、打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON);
3、等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();
4、设置AHB时钟 RCC_HCLKConfig;
5、设置高速AHB时钟 RCC_PCLK2Config;
6、设置低速速AHB时钟 RCC_PCLK1Config;
7、设置PLL RCC_PLLConfig;
8、打开PLL RCC_PLLCmd(ENABLE);
9、等待PLL工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
10、设置系统时钟 RCC_SYSCLKConfig;
11、判断是否PLL是系统时钟 while(RCC_GetSYSCLKSource() != 0x08)
12、打开要使用的外设时钟 RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd() 默认配置背景:定义 STM32F10X_CL,SYSCLK_FREQ_72MHz,USE_STDPERIPH_DRIVER 函数调用顺序: startup_stm32f10x_cl.s(启动文件) → SystemInit() →
SetSysClock () → SetSysClockTo72() SystemInit() 在调用SetSysClock()之前RCC寄存器的值如下(与运算,或运算): RCC->CR = 0x0000 0083; RCC->CIR = 0x00FF0000; RCC->CFGR2 = 0x00000000 1:AHB, APB1,APB2时钟确定 //HCLK = SYSCLK ,从下面的分析可以得出SYSCLK是使用PLLCLK时钟的,也就是72MHZ(至于72MHZ如何得来,请看下面分析) //那么就是HCLK(AHB总线时钟)=PLLCLK = 72MHZ //AHB总线时钟等于系统时钟SYSCLK,也就是 AHB时钟 = HCLK = SYSCLK = 72MHZ /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; //PLCK2等于HCLK一分频, 所以PCLK2 = HCLK,HCLK = 72MHZ, 那么PLCK2(APB2总线时钟) = 72MHZ //APB2总线时钟等于HCLK的一分频,也就是不分频;APB2 时钟 = HCLK = SYSCLK = 72MHZ /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; //PCLK1 = HCLK / 2;PCLK1 等于HCLK时钟的二分频,那么PCLK1(APB1) = 72MHZ / 2 = 36MHZ //APB1总线时钟等于HCLK的二分频,也就是 APB1时钟= HCLK / 2 = 36MHZ /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; 2:如何得出SYSCLK(系统时钟)为72MHZ(外部晶振25MHZ) RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); RCC_CFGR2_PREDIV2_DIV5: PREDIV2 = 5; 5分频也就是PREDIV2对输入的外部时钟 5分频,那么PLL2和PLL3没有倍频前是25 /5 = 5MHZ RCC_CFGR2_PLL2MUL8 : PLL2MUL = 8; 8倍频 8倍频后,PLL2时钟 = 5 * 8 = 40MHZ; 因此 PLL2CLK = 40MHZ RCC_CFGR2_PREDIV1SRC_PLL2 : RCC_CFGR2的第16位为1, 选择PLL2CLK 作为PREDIV1的时钟源 RCC_CFGR2_PREDIV1_DIV5:PREDIV1 = 5;PREDIV1对输入时钟5分频 PREDIV1CLK = PLL2CLK / 5 = 8MHZ 以上是对RCC_CFGR2进行的配置 ------------------------------------------------------------------------------ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL9); RCC_CFGR_PLLXTPRE_PREDIV1 :操作的是RCC_CFGR的第17位PLLXTPRE,操作这一位和操作RCC_CFGR2寄存器的位[3:0]中的最低位是相同的效果 RCC_CFGR_PLLSRC_PREDIV1 :选择PREDIV1输出作为PLL输入时钟 REDIV1CLK = 8MHZ,所以输入给PLL倍频的时钟源是8MHZ RCC_CFGR_PLLMULL9 :PLLMUL = 9;PLL倍频系数为9,也就是对 PLLCLK = PREDIV1CLK * 8 = 72MHZ 以上是对RCC_CFGR进行的配置 ------------------------------------------------------------------------------- RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; //选择PLLCLK作为系统时钟源 ------------------------------------------------------------------------------- 至此基本配置已经完成,配置的时钟如下所述: SYSCLK(系统时钟) = 72MHZ AHB总线时钟 = 72MHZ APB1总线时钟 = 36MHZ APB2总线时钟 = 72MHZ PLL时钟 = 72MHZ PLL2时钟 = 40MHZ;
|