• STM32F2系列时钟的配置


    前一节详细介绍了系统默认的时钟配置,及各路时钟输出是多少,这是默认配置的,但实际使用的时钟默认的时钟并不符合要求,所以就得知道如何调用库函数进行配置。

    最好的资料就是查阅stm32f2xx_rcc.c文件,里面有各种功能函数,并有详细的注释,这让我们这样的新手上手是非常快的。

    //VCO = PLL input clock(HSE or HSI)/PLLM
    //倍频电压后值V =  VCO * PLLN
    //sysclk = V / PLLP
    //PLL48CK = V / PLLQ
    #define PLLM                                 25  //分频因子
    #define PLLN                                 240 //倍频因子
    #define PLLP                                2   //分频因子
    #define PLLQ                                5   //分频因子
    
    vu16 ADC_ConvertedValue[2]; //定义数组,存放PA6和PA7的转换后的数据
    float PA6_AD_value; //压力传感器
    float PA7_AD_value; //锂电池电压
    
    void Delay(__IO uint32_t nCount);
    void SetClock(void);
    int CheckDatas(void);
    
    /* Private functions ---------------------------------------------------------*/
    
    /**
      * @brief  Main program.
      * @param  None
      * @retval None
      */
    int main(void)
    {
        unsigned  int  i = 0;
        RCC_ClocksTypeDef rcc_clocks;
        
        SetClock();
        USART_Config();
        RCC_GetClocksFreq(&rcc_clocks);
        
        printf("
    SYSCLK_Frequency = %d MHz
    ",rcc_clocks.SYSCLK_Frequency/1000000);
        printf("
    HCLK_Frequency = %d MHz
    ",rcc_clocks.HCLK_Frequency/1000000);
        printf("
    PCLK1_Frequency = %d MHz
    ",rcc_clocks.PCLK1_Frequency/1000000);
        printf("
    PCLK2_Frequency = %d MHz
    ",rcc_clocks.PCLK2_Frequency/1000000);
      

    上面是main函数部分代码,时钟设置SetClock()函数,设置完后,可以调用库函数RCC_GetClockFreq(&rcc_clocks)进行查阅配置的时钟是否正确。在使用该函数前,定义一个RCC_ClockTypeDef rcc_clocks结构变量,通过参数传递,就可以访问到RCC_ClockTypeDef里的结构成员变量。


    接下来介绍SetClocks()函数,直接看中文注释

    void SetClock(void)
    {
        RCC_DeInit();//复位系统所有配置时钟
    //    RCC_HSICmd(DISABLE); //RCC_DeInit()后,HSI作为系统时钟,在这调用是不生效的
        RCC_LSICmd(DISABLE);//关闭内部低速时钟
        RCC_PLLI2SCmd(DISABLE);//关闭PLLI2S Clock
        RCC_RTCCLKCmd(DISABLE);//disables the RTC clock
        
        RCC_HSEConfig(RCC_HSE_ON);//外部时钟使能
        while(!RCC_WaitForHSEStartUp());//Waits for HSE start-up
        
        RCC_PLLConfig(RCC_PLLSource_HSE, PLLM, PLLN, PLLP, PLLQ);//配置PLL时钟
        RCC_PLLCmd(ENABLE);  //PLL时钟使能
        while((RCC->CR & RCC_CR_PLLRDY) == 0);//等待PLL 时钟准备好
        
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//PLL CLK 作为系统时钟 sysclk =120M
        RCC_HSICmd(DISABLE);//关闭内部高速时钟,如果内部高速时钟作为系统时钟,此函数不生效
        RCC_HCLKConfig(RCC_SYSCLK_Div1); //AHB = SYSCLK 不分频 120M
        RCC_PCLK1Config(RCC_HCLK_Div4);  //PCLK1 4分频 = 30M
        RCC_PCLK2Config(RCC_HCLK_Div2);  //PCLK2 2分频 = 60M
    }

    这里注意的是HSE时钟使能不是用RCC_HSECmd(ENABLE)这样的函数,而是使用的是RCC_HSEConfig(RCC_HSE_ON),使能后一定要等待HSE start-up,
    同样PLL使能后,也要等待一会,配置时钟时最好按照时钟树结构进行设置,先什么在配置什么,然后PLL时钟先配置在使能,注意一下顺序。

    还要注意一个地方,当不需要内部高速时钟时,使用RCC_HSICmd(DISABLE),不能随调用,可以查看该函数的注释,就是说“如果内部高速时钟作为系统时钟时,该时钟不能停止”也就是说当该时钟作为系统时钟时,调用该函数是无效的,而使用RCC_DeInit()后,内部高速时钟就是作为了系统时钟,所以该函数放置在RCC_SYSCLKConfig()函数后。

    串口打印的数据符合理论算的值,如下图:

    新手的话可能不会在意那些不用的时钟关掉,但是在做项目上,考虑到低功耗时就的把不必要的时钟进行关掉,节省电,还有当处于休眠状态时,也可以考虑降低主时钟,因频率越快,越耗电。

  • 相关阅读:
    总结随笔
    Beta冲刺第七天
    Beta冲刺第六天
    Beta冲刺第五天
    Beta冲刺第四天
    Beta冲刺第三天
    POJ 2240 Arbitrage
    POJ 3660 Cow Contest
    POJ 1797 Heavy Transportation
    LightOJ 1123 Trail Maintenance
  • 原文地址:https://www.cnblogs.com/wen2376/p/4480175.html
Copyright © 2020-2023  润新知