用STM32F4的库函数RCC_PLLConfig()代替SystemInit()手动初始化RCC系统时钟

STM32上电复位后首先执行Reset_Handler,然后调用SystemInit()函数完成时钟等基本初始化,再执行main函数。
; Reset handler
Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main

                 LDR     R0, =SystemInit

                 BLX     R0
                 LDR     R0, =__main
                 BX      R0

                 ENDP

SystemInit()函数在文件system_stm32f4xx.c中。由于该函数中宏定义较多,所以可读性不高,该函数并不能一目了然的看懂STM32F4的各个时钟都配置成了什么样子,笔者归纳总结了库函数和网上的一些资料,自己写了个手动配置RCC时钟的函数如下:

********************************************************************************
* .@1 - 复位 RCC 时钟配置为系统上电复位后的状态
*       系统上电复位后的时钟状态定义如下 - HSI ON and used as system clock source
*                                        - HSE, PLL and PLLI2S OFF
*                                        - AHB, APB1 and APB2 prescaler set to 1
*                                        - CSS, MCO1 and MCO2 OFF
*                                        - All interrupts disabled
*       该函数不改变如下配置:- Peripheral clocks  
*                             - LSI, LSE and RTC clocks  

********************************************************************************  
* .RCC_PLLConfig(RCC_PLLSource, PLLM, PLLN, PLLP, PLLQ)
*
*      RCC_PLLSource - PLL输入时钟源:RCC_PLLSource_HSI/RCC_PLLSource_HSE 之一
*                      .........................................................
*      PLLM          - 分频因数,用来生成PLL VCO输入时钟,该时钟范围:1~2M
*                      RCC_PLLSource/PLLM = PLL VCO输入时钟
*                      该分频因数的范围:2~63
*                      .........................................................
*      PLLN          - 倍频因数,PLL VCO输入时钟*PLLN = PLL VCO输出时钟
*                      PLL VCO输出时钟范围:192~432M
*                      .........................................................
*      PLLP          - 分频因数,用于生成SYSCLK
*                      PLL VCO输出时钟/PLLP = SYSCLK
*                      该分频因数的范围:2,4,6 OR 8
*                      .........................................................
*      PLLQ          - USB OTG FS, SDIO and RNG(随机数发生器)时钟的分频因数
*                      USB OTG FS需要48M的时钟以正常工作
*                      SDIO and RNG(随机数发生器)时钟 <= 48M
*                      该分频因数的范围:2~15
*      .........................................................................
*      PLL_VCO                        =  (RCC_PLLSource/PLLM)*PLLN
*      SYSCLK                         = ((RCC_PLLSource/PLLM)*PLLN) / PLLP
*      USB OTG FS, SDIO and RNG Clock = ((RCC_PLLSource/PLLM)*PLLN) / PLLQ
*      .........................................................................
*                                                                                             2018-01-27
********************************************************************************
*/
void RCC_MyConfig(void)
{
    RCC_DeInit();                                                              //@1
    RCC_HSEConfig(RCC_HSE_ON);                                   //打开外部时钟
    
    if(RCC_WaitForHseStartUp() == SUCCESS)                  //等待外部时钟成功启动
    {
        //RCC_PLLCmd(DISABLE);    //配置PLL前应先关闭主PLL
        
        RCC_SYSCLKConfig(RCC_SYSCLKSOURCE_PLLCLK);      //选择PLL时钟为系统时钟
        
        RCC_HCLKConfig(RCC_SYSCLK_Div1);                          //HCLK(AHB)时钟为系统时钟1分频
        
        RCC_PCLK1Config(RCC_HCLK_Div4);                            //PCLK(APB1)时钟为HCLK时钟8分频
        RCC_PCLK2Config(RCC_HCLK_Div2);                            //PCLK(APB2)时钟为HCLK时钟2分频
        
        RCC_PLLConfig(RCC_PLLSource_HSE, 25, 336, 2, 7);     //PLL时钟配置,外部晶振为25MHz,系统配置为168MHz
        
        RCC_PLLCmd(ENABLE);                                               //开启PLL时钟,并等待PLL时钟准备好
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
        
        while(RCC_GetSYSCLKSource() != 0x08);                      //Wait till PLL is used as system clock source
    }
}

看过上面的文章,读者可能有不懂的一个地方就是PLL VCO,那么,PLL,是倍频电路,我们把PLL倍频电路看作一个黑匣子,它是有输入和输出的,RCC_PLLSource经过PLLM分频后,就得到了这个黑匣子的输入时钟,这个输入时钟经过PLLN倍频后,就得到了黑匣子的输出时钟,OK,这个时钟就叫做PLL VCO

初学者可能第一遍看不懂,没关系,中国有句谚语:书读百遍自然熟,水平再高的人,也是这么学出来的,况且这个函数根本用不着读百遍,估计读个2~3遍就搞定了,如还有疑问,请到老匠人电子里找我:)

你可能感兴趣的:(STM32)