stm32系统时钟学习笔记

发布者:Haifeeng最新更新时间:2022-08-01 来源: csdn关键字:stm32  系统时钟  频率 手机看文章 扫描二维码
随时随地手机看文章

在这里插入图片描述

HSE:高速外部时钟

来源:有源晶振(1-50M),无源晶振(4-26M)

控制:RCC_CR时钟控制寄存器的位16:HSEON控制

HSI:高速内部时钟

来源:芯片内部,大小为16M,当HSE故障时,系统自动切换到HSI,直到HSE启动成功

控制:RCC_CR时钟控制寄存器的位0:HSION控制

锁相环时钟:PLLCLK

来源:HSI、HSE。由PLLSRC位配置

HSE或者HSI先经过一个分频因子M进行分频,然后再经过倍频因子N,然后在经过分频因子P,最后成为锁相环时钟

VCOCLK_IN = PLLCLK_IN / M = HSE / 25 = 1M

VCOCLK_OUT = VCOCLK_IN * N =1M * 336 = 336M

PLLCLK_OUT=VCOCLK_OUT/P=336/2=168M 

PLL48CK时钟:USB_FS、RANG、SDIO提供时钟


系统时钟 SYSCLK,最高为168M

来源:HSI、HSE、PLLCLK

控制:RCC_CFGR时钟配置寄存器SW位


HCLK时钟 :AHB高速总线时钟,最高为168M

在这里插入图片描述

来源:系统时钟分频得到

控制:RCC_CFGR时钟配置寄存器的HPRE位


PCLK1时钟:APB1低速总线时钟,最高为42M,为APB1总显得外设提供时钟

来源:HCLK分频得到,通常为4分频

控制:RCC_CFGR时钟配置寄存器的PPRE1位


PCLK2时钟:APB高速总线时钟,最高为84M,为APB2总显得外设提供时钟

来源:HCLK分频得到,通常配置为2分频

控制:RCC_CFGR时钟配置寄存器的PPRE2位


将 system_stm32f4xx.c 文件中的void SystemInit(void) 函数中的 ==SetSysClock()==摘抄出来,去掉宏定义,和与STM32F40_41xxx无关的代码,只保留有关STM32F40_41xxx的内容进行分析:


 #define PLL_M      25

 #define PLL_Q      7

 #define PLL_N      336

 #define PLL_P      2

 void User_SetSysClock(void)

{

/******************************************************************************/

/*            PLL (clocked by HSE) used as System clock source                */

/******************************************************************************/

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  RCC_DeInit();//复位RCC所有寄存器

  /* Enable HSE */

/*使能HSE*/

  RCC->CR |= ((uint32_t)RCC_CR_HSEON);//控制RCC_CR寄存器中的HSEON位置为1,使能

 

  /* Wait till HSE is ready and if Time out is reached exit */

/*等待HSE启动稳定(通过HSEDAY位来判断),如果超时则退出*/

  do

  {

    HSEStatus = RCC->CR & RCC_CR_HSERDY;//控制RCC_CR寄存器中的HSERDY位置

    StartUpCounter++;

  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));


  if ((RCC->CR & RCC_CR_HSERDY) != RESET)

  {

    HSEStatus = (uint32_t)0x01;

  }

  else

  {

    HSEStatus = (uint32_t)0x00;

  }

/*HSE启动成功*/

  if (HSEStatus == (uint32_t)0x01)

  {

    /* Select regulator voltage output Scale 1 mode */

/*选择电压调节器的模式为1*/

    RCC->APB1ENR |= RCC_APB1ENR_PWREN;

    PWR->CR |= PWR_CR_VOS;


    /* HCLK = SYSCLK / 1*/ // AHB  1分频

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;


    /* PCLK2 = HCLK / 2*/ // APB2  2分频

    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

    

    /* PCLK1 = HCLK / 4*/ // APB1  4分频

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;



    /* Configure the main PLL */

/*配置主PLL*/    //PLL_M分频因子(现在定义为25),如果外部晶振有变化需要更改,代码移植时会用到

    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);//RCC_PLLCFGR_PLLSRC_HSE 选择锁相环时钟的来源,一般都是HSE,一般不使用HSI



    

    /* Enable the main PLL */

/*使能主PLL*/

    RCC->CR |= RCC_CR_PLLON;


    /* Wait till the main PLL is ready */

/*等待主PLL稳定*/

    while((RCC->CR & RCC_CR_PLLRDY) == 0)

    {

    }


    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */

/*配置FLASH预取指,指令缓存,数据缓存,等待周期*/

    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;



    /* Select the main PLL as system clock source */

/*选择主PLL时钟作为系统时钟*/

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= RCC_CFGR_SW_PLL;


    /* Wait till the main PLL is used as system clock source */

/*确保主PLL时钟选为系统时钟*/

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);

    {

    }

  }

  else

  { /* If HSE fails to start-up, the application will have wrong clock

         configuration. User can add here some code to deal with this error */

/*HSE 启动失败,在理可以添加启动失败的处理代码*/

  }

}


适用固件库的方式编写SetSysClock()

 void HSE_SetSysClock(uint32_t PLLM,uint32_t PLLN,uint32_t  PLLP,uint32_t PLLQ)

{

ErrorStatus HSE_ErrorStatus = ERROR;

 

RCC_DeInit();//复位RCC所有寄存器

 

/*使能HSE*/

RCC_HSEConfig(RCC_HSE_ON);

 

/*等待HSE启动稳定*/

HSE_ErrorStatus=RCC_WaitForHSEStartUp();

if(HSE_ErrorStatus == SUCCESS){

/*启动成功*/

/*选择电压调节器的模式为1*/

    RCC->APB1ENR |= RCC_APB1ENR_PWREN;

    PWR->CR |= PWR_CR_VOS;

/*配置AHB、APB1、APB2预分频系数*/

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK1Config(RCC_SYSCLK_Div4);

RCC_PCLK2Config(RCC_SYSCLK_Div2);

/*配置主PLL*/    //PLL_M分频因子(以参数的方式传进来),如果外部晶振有变化需要更改,代码移植时会用到

RCC_PLLConfig( RCC_PLLSource_HSE,PLLM,PLLN, PLLP,PLLQ);//锁相环时钟:PLLM 分频因子      PLLN 倍频因子    PLLP分频因子     PLLQ 分频因子

/*使能主PLL*/

    RCC_PLLCmd(ENABLE);

/*等待主PLL稳定*/

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET){

}

/*配置FLASH预取指,指令缓存,数据缓存,等待周期*/

    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

/*选择主PLL时钟作为系统时钟*/

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/*确保主PLL时钟选为系统时钟*/

     while(RCC_GetSYSCLKSource()!=0x08){

}

}

else{

/*HSE启动失败,在这里添加错误处理代码*/

}


准确检测时钟信号的频率方法:MCO1,MCO2 通过外部GPIO输出,用示波器进行检测

在这里插入图片描述

初始化MCO1、MCO2对应的GPIO引脚,调用图中两个函数,从PA8、PC9引出两条线接示波器进观察频率

在这里插入图片描述

关键字:stm32  系统时钟  频率 引用地址:stm32系统时钟学习笔记

上一篇:STM32F407中断学习笔记
下一篇:error: #268: declaration may not appear after executable statement in block问题解决方法

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved