欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > 05:(寄存器开发)时钟树

05:(寄存器开发)时钟树

2025/2/7 21:54:11 来源:https://blog.csdn.net/qq_51284092/article/details/143640666  浏览:    关键词:05:(寄存器开发)时钟树

时钟树

  • 1、时钟树的简介
  • 2、相关寄存器与配置
  • 3、代码实验

1、时钟树的简介

   每次在使用单片机的片上外设之前,第一步就是开启此外设的时钟(内核外设除外)。这一步就像是开关,只有开启了时钟,这个外设才能正常的使用。我们知道STM32有很多的片上外设,他们挂载的对应的时钟总线如下图所示。
      在这里插入图片描述

那么这些时钟总线APB1,APB2,AHB的时钟频率是如何改变的喃?这就与时钟树有关。

2、相关寄存器与配置

  如下图就是STM32F103C8T6的时钟树。总线AHB频率不能超过72MHz,APB1频率不能超过36MHz,APB2频率不能超过72MHz。其中系统时钟SystemClock的时钟来源由HSI(8MHz),HSE(8MHz),PLL(8~72MHz)。SystemClock经过分频后得到AHB总线时钟频率,AHB总线时钟结果分频得到APB1总线和APB2总线时钟频率。

在这里插入图片描述

1.HSE
    外部高速晶振,一般可提供4~16MHz的频率,而我们使用的最小系统板的外部高速晶振为8MHz。
    与之相关的寄存器如下:
在这里插入图片描述

 /*开启外部高速晶振HSE*/RCC->CR |= RCC_CR_HSEON;//开启HSEwhile(!(RCC->CR & RCC_CR_HSEON));//等待开启成功

2.HSI
    内部高速晶振,是单片机内部提供,一般为8MHz。和HSE相比,稳定性和精度不如HSE。
    与之相关的寄存器如下:
在这里插入图片描述

/*开启内部晶振HSI*/
RCC->CR |= RCC_CR_HSION;//开启HSI
while(!(RCC->CR & RCC_CR_HSIRDY));//等待开启成功

3.HSE Prescaler
    内部高速晶振HSE的分频器:一般为1分频(不分频),2分频。
    与之相关的寄存器如下:
在这里插入图片描述

// 配置 PLLXTPRE 为 1,意味着 HSE 时钟将进行 2 分频后送入 PLL
RCC->CFGR |= RCC_CFGR_PLLXTPRE;  // 设置 PLLXTPRE 为 1
// 配置 PLLXTPRE 为 0,意味着 HSE 时钟不进行分频,直接送入 PLL
RCC->CFGR &= ~RCC_CFGR_PLLXTPRE;  // 清除 PLLXTPRE 为 0

4.PLL Source Mux
    PLL输入时钟源选择。可选2分频后的HSI,未分频/分频的HSE。
    与之相关的寄存器如下:
在这里插入图片描述

/*配置PLL输入时钟源为HSE:RCC_CFGR_PLLSRC = 1*/
RCC->CFGR |= RCC_CFGR_PLLSRC;

5.PLLMul
    PLL倍频器,倍率2~16
    与之相关的寄存器如下:
在这里插入图片描述

/* 设置PLL倍频为9(只有PLL未开启才能配置):RCC_CFGR_PLLMULL[3:0] */
RCC->CFGR |= RCC_CFGR_PLLMULL;
RCC->CFGR &= ~RCC_CFGR_PLLMULL_3;//配置为0111

在这里插入图片描述

/*使能PLL:RCC_CR_PLLON = 1*/
RCC->CR |= RCC_CR_PLLON;//使能PLL
while(!(RCC->CR & RCC_CR_PLLRDY));//等待使能成功

6.System Clock Mux
    系统SystemClock时钟源选择。可选HSI作为系统时钟源,HSE作为系统时钟源,PLL作为系统时钟源。
    与之相关的寄存器如下:
在这里插入图片描述

/*配置为选择PLL:RCC_CFGR_SW[1:0] = 10 */
RCC->CFGR &= ~RCC_CFGR_SW_0;
RCC->CFGR |= RCC_CFGR_SW_1;

7.AHB Prescaler
    AHB总线时钟预分频器,将系统时钟SystemClock进行分频后得到AHB总线时钟频率。分频系数1~512
    与之相关的寄存器如下:
在这里插入图片描述

/*设置AHB分频为1分频:RCC_CFGR_HPRE[3:0] = 0XXX*/
RCC->CFGR &= ~RCC_CFGR_HPRE_3;

8.APB1 Prescaler
    APB1总线时钟预分频器,将AHB总线时钟频率进行分频后得到APB1总线时钟频率。分频系数1~16
    与之相关的寄存器如下:
在这里插入图片描述

/*设置APB1为2分频:RCC_CFGR_PPRE1[2:0] = 100 */
RCC->CFGR &= ~(RCC_CFGR_PPRE1_0 |RCC_CFGR_PPRE1_1);
RCC->CFGR |= RCC_CFGR_PPRE1_2;

9.APB2 Prescaler
    APB2总线时钟预分频器,将AHB总线时钟频率进行分频后得到APB2总线时钟频率。分频系数1~16
    与之相关的寄存器如下:
在这里插入图片描述

/*设置APB2为1分频:RCC_CFGR_PPRE2[2:0] = 0xx*/
RCC->CFGR &= ~RCC_CFGR_PPRE2_2;

3、代码实验

实验:将系统时钟SystemClock配置为72MHz,AHB总线时钟配置为72MHz,APB1总线时钟配置为36MHz,APB2总线时钟配置为72MHz。
配置代码如下:

void Config_SystemClock(void)
{/* 1、使能外部高速晶振HSE:RCC_CR_HSEON = 1(因为停机模式使HSE停止了,所以要使能)*/RCC->CR |= RCC_CR_HSEON;/* 2、等待开启成功:RCC_CR_HSERDY = 1 */while(!(RCC->CR & RCC_CR_HSERDY));//系统默认HSE未分频,所以可以不用配置HSE Prescaler/* 3、配置PLL输入时钟源为HSE:RCC_CFGR_PLLSRC = 1 */RCC->CFGR |= RCC_CFGR_PLLSRC_HSE;/* 4、设置PLL倍频为9(只有PLL未开启才能配置):RCC_CFGR_PLLMULL[3:0] */RCC->CFGR |= RCC_CFGR_PLLMULL;RCC->CFGR &= ~RCC_CFGR_PLLMULL_3;//配置为0111/* 3、使能PLL:RCC_CR_PLLON = 1 */RCC->CR |= RCC_CR_PLLON;	/* 5、等待开启成功:RCC_CR_PLLRDY*/while(!(RCC->CR & RCC_CR_PLLRDY));/* 6、配置系统时钟源为选择PLL:RCC_CFGR_SW[1:0] = 10 */RCC->CFGR &= ~RCC_CFGR_SW_0;RCC->CFGR |= RCC_CFGR_SW_1;//系统时钟SystemClock = 72MHz/* 7、设置AHB分频为1分频:RCC_CFGR_HPRE[3:0] = 0XXX */RCC->CFGR &= ~RCC_CFGR_HPRE_3;//AHB总线时钟 = 72MHz/* 8、设置APB2为1分频:RCC_CFGR_PPRE2[2:0] = 0xx*/RCC->CFGR &= ~RCC_CFGR_PPRE2_2;//APB2总线时钟 = 72MHz/* 9、设置APB1为2分频:RCC_CFGR_PPRE1[2:0] = 100 */RCC->CFGR &= ~(RCC_CFGR_PPRE1_0 |RCC_CFGR_PPRE1_1);RCC->CFGR |= RCC_CFGR_PPRE1_2;//APB1总线时钟 = 36MHz
}

  上面的代码成功将系统时钟SystemClock配置为72MHz,AHB总线时钟配置为72MHz,APB1总线时钟配置为36MHz,APB2总线时钟配置为72MHz。
  但是,还存在一个细节的疏忽,就是Flash参数的设置。因为代码存储在Flash中,要想CPU将Flash中的代码取出来进行执行,那么系统时钟SystemClock频率和Flash时钟频率同步。而Flash的时钟频率最大值为24MHz。所以需要添加系统时钟的等待。相关寄存器如下:
在这里插入图片描述
综上:完整的代码如下:

void Config_SystemClock(void)
{/* Flash参数的设置 */FLASH->ACR |= FLASH_ACR_PRFTBE;//使能Flash预取缓冲区/* 设置系统时钟进行2个等待周期 :FLASH_ACR_LATENCY[2:0] = 010*/FLASH->ACR &= FLASH_ACR_LATENCY_0;//FLASH_ACR_LATENCY_0   ((uint8_t)0x00)FLASH->ACR |= FLASH_ACR_LATENCY_2;//FLASH_ACR_LATENCY_2   ((uint8_t)0x02)/* 1、使能外部高速晶振HSE:RCC_CR_HSEON = 1(因为停机模式使HSE停止了,所以要使能)*/RCC->CR |= RCC_CR_HSEON;/* 2、等待开启成功:RCC_CR_HSERDY = 1 */while(!(RCC->CR & RCC_CR_HSERDY));//系统默认HSE未分频,所以可以不用配置HSE Prescaler/* 3、配置PLL输入时钟源为HSE:RCC_CFGR_PLLSRC = 1 */RCC->CFGR |= RCC_CFGR_PLLSRC_HSE;/* 4、设置PLL倍频为9(只有PLL未开启才能配置):RCC_CFGR_PLLMULL[3:0] */RCC->CFGR |= RCC_CFGR_PLLMULL;RCC->CFGR &= ~RCC_CFGR_PLLMULL_3;//配置为0111/* 3、使能PLL:RCC_CR_PLLON = 1 */RCC->CR |= RCC_CR_PLLON;	/* 5、等待开启成功:RCC_CR_PLLRDY*/while(!(RCC->CR & RCC_CR_PLLRDY));/* 6、配置系统时钟源为选择PLL:RCC_CFGR_SW[1:0] = 10 */RCC->CFGR &= ~RCC_CFGR_SW_0;RCC->CFGR |= RCC_CFGR_SW_1;//系统时钟SystemClock = 72MHz/* 7、设置AHB分频为1分频:RCC_CFGR_HPRE[3:0] = 0XXX */RCC->CFGR &= ~RCC_CFGR_HPRE_3;//AHB总线时钟 = 72MHz/* 8、设置APB2为1分频:RCC_CFGR_PPRE2[2:0] = 0xx*/RCC->CFGR &= ~RCC_CFGR_PPRE2_2;//APB2总线时钟 = 72MHz/* 9、设置APB1为2分频:RCC_CFGR_PPRE1[2:0] = 100 */RCC->CFGR &= ~(RCC_CFGR_PPRE1_0 |RCC_CFGR_PPRE1_1);RCC->CFGR |= RCC_CFGR_PPRE1_2;//APB1总线时钟 = 36MHz
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com