STM32F1时钟树配置

时钟来源有四个:外部高速晶振HSE(一般是8M),外部低速晶振(32.768K)。内部高速RC振荡器HSI(8M),内部低速RC振荡器LSI(40K)。内部的时钟一般没有外部晶振准,一般用外部时钟来初始化。在STM32F1系列库函数文件里包含一个文件

******************************************************************************
  * @file system_stm32f10x.c
  * 作者:MCD 应用团队
  * 版本 V3.5.0
  * @日期 2011 年 3 月 11 日
  * @brief CMSIS Cortex-M3 器件外设访问层系统源文件。
  * 
  * 该文件提供了两个函数和一个全局变量,可从以下应用程序调用 
  * 用户应用程序调用:
  * SystemInit(): 设置系统时钟(系统时钟源、PLL 倍增器、AHB/APF
  * 系数、AHB/APBx 预分频器和闪存设置)。
  * 该函数在重置后启动时调用,并在分支到主程序之前调用。
  * 在分支到主程序之前调用。该调用在
  * stm32f10x_xx.s "文件中调用。
  *
  * SystemCoreClock 变量: 包含内核时钟 (HCLK),用户应用程序可以使用它来设置系统内核时钟。
  * 用户应用程序可使用它来设置 SysTick 
  * 定时器或配置其他参数。
  *                                     
  * - SystemCoreClockUpdate(): 更新变量 SystemCoreClock,每当内核时钟发生变化时必须调用。
  * 在程序执行过程中改变核心时钟时
  * 在程序执行过程中

2. 每次设备复位后,HSI(8 MHz)都被用作系统时钟源。
  * 然后调用 "startup_stm32f10x_xx.s "文件中的 SystemInit() 函数,以
  * 在分支到主程序之前配置系统时钟。
  *
  * 如果用户选择的系统时钟源无法启动,SystemInit()
  * 函数将不起作用,HSI 仍将用作系统时钟源。用户可以 
  * 在 SetSysClock() 函数中添加一些代码来解决这个问题。
  *
  4. HSE 晶体的默认值设置为 8 MHz(或 25 MHz,取决于*所使用的产品),请参阅 "HSE"。
  * 请参阅 "stm32f10x.h "文件中的 "HSE_VALUE "定义。
  * 直接或通过 PLL 将 HSE 用作系统时钟源时,如果使用不同的晶振,则必须对 HSE_VALUE 进行调整。
  * 当 HSE 直接或通过 PLL 用作系统时钟源,而您使用不同的晶振时,您必须调整 HSE 值以适应您自己的
  * 配置。
  *        
  ******************************************************************************
  * 注意
  *
  * 本固件仅供参考,旨在为客户提供
  * 本固件仅供参考,旨在为客户提供有关其产品的编码信息,以便客户节省
  * 时间。因此,意法半导体公司不承担任何
  * 因此,对于因这些固件和软件的内容而引起的任何索赔,意法半导体不承担任何直接、间接或间接的损害赔偿责任。
  * 因此,对于因此类固件的内容和/或客户使用其中包含的
  * 编码信息而引起的任何索赔。
  *

在单片机上电后会自动初始化好时钟来源与主频。可以通过修改这个文件来达到自己时钟源初始化的配置

 一般我们配置时钟源来自外部高速晶振不分频,经过锁相环倍频9倍后,得到72M时钟。配置系统时钟来源倍频器。然后SYSCLK就是来源于PLL的72M主频了,可以通过RCC库函数来查询SYSCLK时钟来源。然后就是配置AHB分频器,选择不分频,因为我们要得到HCLK-->72M。系统滴答定时器的时钟来源默认是HCLK,这样我们就可以在滴答定时器里计数72得到1us的延时。从而实现相对于准确的延时函数。APB1总线是低速外设总线,如果系统时钟是72M,那么它只能选择最大36M的频率,所以要经过APB1分频2,得到PCLK1-->36M。APB2是高速外设总线,可以不用管,它默认就是不分频。

然后就是实时时钟RTC,一般是用来做和实时相关的东西使用的,像闹钟啊。它的时钟来源可以来自HSE分频128,LSE,LSI。LSI在使用之前一般都要进行校准。

最后MCO是时钟输出,将单片机的时钟向外部输出,来源有4个:锁相环分频2,HSI,HSE,SYSCLK。

以下是配置开启HSE,HSE不分频,锁相环9倍频,系统时钟来自锁相环,HCLK(72M),PCLK1(36M),PCLK2(36M)的代码示例

void SystemClock_Config(void) {
  ErrorStatus HSEStartUpStatus;

  // 启用外部高速振荡器(HSE)
  RCC_HSEConfig(RCC_HSE_ON);

  // 等待外部高速振荡器稳定
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS) {
    // 外部高速振荡器稳定,配置 PLL
     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  // 8MHz * 9 = 72MHz  

    // 使能 PLL
    RCC_PLLCmd(ENABLE);

    // 等待 PLL 稳定
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    // 配置系统时钟为 PLL
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    // 等待系统时钟配置完成
    while (RCC_GetSYSCLKSource() != 0x08);
  } else {
  
    RCC_HSICmd(ENABLE);

    // 等待内部高速振荡器稳定
    while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
    
      // 使能 PLL
    RCC_PLLCmd(ENABLE);
    
    // 配置 PLL
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);  // 8MHz / 2 * 16 = 64MHz


    // 等待 PLL 稳定
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

    // 配置系统时钟为 PLL
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    // 等待系统时钟配置完成
    while (RCC_GetSYSCLKSource() != 0x08);
  }
  // 配置HCLK分频因子为1,即HCLK等于SYSCLK
  RCC_HCLKConfig(RCC_SYSCLK_Div1);

  // 配置PCLK1分频因子为2,即PCLK1等于HCLK除以2
  RCC_PCLK1Config(RCC_HCLK_Div2);

  // 配置PCLK2分频因子为2,即PCLK2等于HCLK除以2
  RCC_PCLK2Config(RCC_HCLK_Div1);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值