STM32-时钟启动的两个寄存器(RCC

    科技2022-07-11  115

    本文基于STM32F407ZGT6 ————————————— STM32可以使用三种不同的时钟源来驱动系统时钟 (SYSCLK): ● HSI 振荡器时钟 ● HSE 振荡器时钟 ● 主 PLL (PLL) 时钟 器件具有以下两个次级时钟源: ● 32 kHz 低速内部 RC (LSI RC),该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用 于停机/待机模式下的自动唤醒。 ● 32.768 kHz 低速外部晶振(LSE 晶振),用于驱动 RTC 时钟 (RTCCLK)

    下图是STM32库函数中系统时钟的启动过程。 PLL时钟来源是外部高速时钟(HSE); PLL经过倍频达到168MHZ; 最后系统选择采用的是PLL时钟。所以SYSCLK=168MHZ。 在STM32时钟配置过程中主要配置三个寄存器:

    RCC 时钟控制寄存器 (RCC_CR)

    RCC寄存器需要配置也非常多,操作频繁,建议直接看源码和中文参考手册。 主要配置的两个寄存器:

    RCC 时钟配置寄存器 (RCC_CFGR)RCC PLL 配置寄存器 (RCC_PLLCFGR)

    RCC_PLLCFGR如果是使用PLL作为系统时钟该寄存器需要配置(一般都是用PLL作为系统时钟的,这样才能使系统时钟达到168M)

    一、关于RCC_CFGR的配置:

    在库函数里面关于CFGR主要是设置了HCLK、APB1和APB2的时钟频率,还有通过寄存器后两位选择HSE/HSI/PLL这三个其中一个作为系统时钟。 在void SystemInit(void)函数里面: 将CRR_CFGR寄存器复位

    /* Reset CFGR register */ //复位时钟配置寄存器 RCC->CFGR = 0x00000000;

    在函数static void SetSysClock(void)函数里面: 1、将HCLK设置为SYSCLK的频率,即HCLK频率为168MHZ

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

    RCC_CFGR_HPRE_DIV1=0x00000000;时钟不分频 2、将APB2设置为系统时钟二分频,即84MHZ

    /* PCLK2 = HCLK / 2*/ //将CFGR的15位置1,即PPRE2为100,PCLK2为HCLK二分频 RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

    RCC_CFGR_PPRE2_DIV2=0x00008000;15:13设置为100 3、将APB1设置为四分频,即42MHZ

    /* PCLK1 = HCLK / 4*/ //将CFGR的10、12位置1,即PPRE1为101,PCLK1为HCLK四分频 RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

    RCC_CFGR_PPRE1_DIV4=0x0000A000;APB1为AHB四分频,位12:10设置为101。APB1频率为42M。

    二、关于PLL_CFGR的配置

    在void SystemInit(void)函数里面: 将PLLCFGR复位

    /* Reset PLLCFGR register */ //0x24003010是PLLCFGR的默认复位值,中文参考手册有写 RCC->PLLCFGR = 0x24003010;

    在函数static void SetSysClock(void)函数里面: 此寄存器用于根据公式配置 PLL 时钟输出: ● f(VCO 时钟) = f(PLL 时钟输入) × (PLLN / PLLM) ● f(PLL 常规时钟输出) = f(VCO 时钟) / PLLP ● f(USB OTG FS, SDIO, RNG 时钟输出) = f(VCO 时钟) / PLLQ

    /* Configure the main PLL */ /*这个语句比较复杂,我把它分出来就是把值0x0740 0d88赋值给PLLCFGR 就是把PLLCFGR的第3、7、8、10、12、14、22、24、25、26位置1(0X0740 5408) 第22位置1,选择 HSE 振荡器时钟作为 PLL 和 PLLI2S 时钟输入 其中:PLLQ=7;PLLP=2;PLLN=336;PLLM=8 计算公式: ● f(VCO 时钟) = f(PLL 时钟输入) × (PLLN / PLLM) ● f(PLL 常规时钟输出) = f(VCO 时钟) / PLLP ● f(USB OTG FS, SDIO, RNG 时钟输出) = f(VCO 时钟) / PLLQ */ RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

    设置PLL为输入时钟

    最后,把上述配置好了就可以通过CRR_CFGR寄存器的最后两位把系统时钟改为PLL了,如果想要修改输入时钟为内部高速时钟HSI或者是外部高速时钟HSE,在这一步下手即可。

    /* Select the main PLL as system clock source */ //把CFGR的后两位清零,第二位置1,系统时钟由HSE更改为PLL //如果想改时钟输入在这一步改即可 RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= RCC_CFGR_SW_PLL;

    RCC_CFGR_SW=0x00000003 RCC_CFGR_SW_PLL=0x00000002

    本文主要是具体代码剖析,整体讲解可以看:从库函数看STM32时钟启动过程

    Processed: 0.016, SQL: 8