danruhai 发表于 2020-8-26 09:14:14

用STM32F4的库函数RCC_PLLConfig()代替SystemInit()手动初始化

STM32上电复位后首先执行Reset_Handler,然后调用SystemInit()函数完成时钟等基本初始化,再执行main函数。

; Reset handler
Reset_Handler    PROC
               EXPORTReset_Handler            
      IMPORTSystemInit
      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

关键字:STM32F4库函数RCC_PLLConfig()SystemInit()手动初始化

清心如水 发表于 2020-8-28 08:32:53

h09721 发表于 2020-8-28 08:55:18

sun5304 发表于 2020-8-31 07:28:36

leslie_aqiang 发表于 2021-1-31 08:54:09

加油加油加油呦
页: [1]
查看完整版本: 用STM32F4的库函数RCC_PLLConfig()代替SystemInit()手动初始化