STM32F4 RCC及SystemInit配置分析

转自http://bbs.21ic.com/blog-976962-120828.html

 进入System函数,第一条语句是  
RCC->CR |= (uint32_t)0x00000001;         也就是使能HSI内部振荡器。
接着是
RCC->CFGR = 0x00000000;
    清零RCC_CFGR寄存器.  
接着是  
RCC->CR &= (uint32_t)0xFEF6FFFF;    
就是将HSE设置为OFF,CSSON和PLL叶设置为OFF。
接着是  复位RCC_PLLCFGR寄存器
RCC->PLLCFGR = 0x24003010;
    高4位保留,将PLLQ=4;将PLL和PLLI2S的时钟源设置为HSI;
设置PLLP=2,即系统时钟为主PLL输出时钟的2分频;设置PLLN=192;设置PLLM=16;

然后是  RCC->CR &= (uint32_t)0xFFFBFFFF;
    就是将HSEBYP位清零,即HSE时钟不被旁路了。
然后是   RCC->CIR = 0x00000000;
    Disable所有中断。
然后函数里调用了另一个函数 SetSysClock();

开始是      
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
    将RCC_CR寄存器的第16位置1了,也就是Enable HSE;

然后在一个do while循环里不断读取HSEDRY的状态,当HSE时钟已经ready好,该位置1时,就会跳出循环。
(时钟启动超时也会跳出循环。这个超时量被设置为0x05000,每次循环就会自增,超过这个值之前,HSERDY还没置1,也会退出循环。)
退出循环后判断HSERDY的状态,ready则为1状态,否则为0;

当状态为1时,开始
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
    打开APB1时钟的电源。
接着是        
PWR->CR |= PWR_CR_VOS;
    看PWR->CR这个寄存器,这是设置性能与功耗的平衡的,不太懂。
接着是        
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
    HCLK不分频。
RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
    PCLK2 = HCLK/2;
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
    PCLK1 = HCLK/4;
接着是   
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
        
配置主PLL的参数,这个PLL_M、PLL_P、PLL_N、PLL_M等都是一个宏定义,在函数用一个文件的开头处,可以设置。
计算公式:
        SYSCLK = PLL_VCO / PLL_P
        PLL_VCP = (HSE_VALUE / PLL_M) * PLL_N
例如,外部晶振HSE_VALUE = 25MHz,PLL_M =25,PLL_N = 336,PLL_P=2;则系统时钟为168Mhz。
HCLK不分频为168MHZ,PCLK2=84MHZ,PCLK1=42MHZ。
接着        
RCC->CR |= RCC_CR_PLLON;
     Enable the main PLL;
然后一直循环等待PLLRDY置1。
然后有个FLASH存取控制寄存器的设置,懒得看了,跳过。
最后    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
    就是将SYSCLK时钟源切换成主PLL的输出。
最后一个while循环等待,切换成功后退出循环。

你可能感兴趣的:(stm32)