STM32
直播中

偶是糕富帅

11年用户 788经验值
私信 关注
[问答]

请问一下stm32时钟树是由哪些部分组成的

为什么STM32要设计如此复杂的时钟树呢?

stm32时钟树是由哪些部分组成的?

回帖(1)

庞哲

2021-11-8 09:56:12
  为什么stm32要设计如此复杂的时钟树?
  大大节省功耗,需要用到的外设开启时钟,不需要的则关闭,这将大大节省功耗。
  系统时钟要了然于胸,脑子中得存储着时钟树框图,能复述具体时钟的配置过程。
  一、总体时钟树框图
  
  
  时钟源(如上图的左边4个蓝色框所示):
  HSI RC
  HSE Osc
  LSE Osc
  LSI RC
  倍频器与分频器:
  PLL 锁相环、TIMx Multiplier,起倍频作用。
  AHB Prescaler、APB1Prescaler、APB2Prescaler、USB Prescaler起分频作用。
  时钟输出:
  HCLK:内核CPU时钟
  PCLK1:外设1时钟
  TIMxCLK:通用定时器时钟
  PCLK2:TIM1时钟
  ADCCLK:ADC时钟
  USBCLK:USB 48MHz时钟
  RTCCLK:RTC时钟
  IWDGCLK:独立看门狗时钟
  MOC:可以选择输出SYSCLK、HSI、HSE、PLLCLK的其中一个,用示波器连接此接口判断时钟是否故障。此接口也可提供晶振。
  css时钟监视系统:
  自动切换时钟来源
  通常以HSE作为时钟源产生HCLK供CPU使用,万一HSE失效了,CPU就无法正常工作了。为了增加健壮性,stm32时钟系统中使用css时钟监视系统,在HSE失效的时候,产生中断,自动切换选择HSI作为时钟源。
  二、主系统时钟
  2.1 总体介绍
  追溯根源,起时钟来源于 HSE 或者 HSI 。
  HSE、HSI 可经过 锁相环 倍频后作为 SYSCLK系统时钟 ,或者直接作为 SYSCLK系统时钟 。通过SW进行选择。
  SYSCLK系统时钟 经过 AHB 预分频器 分频后,作为 FCLK时钟 (作为CPU时钟)、HCLK高速时钟(用于高速外设,比如内存控制器,中断控制器,LCD控制器, DMA 等)。
  SYSCLK系统时钟 经过 AHB 预分频器 及 APB1 预分频器 分频后,作为 PCLK1时钟 (主要用于低速外设)。
  SYSCLK系统时钟 经过 AHB 预分频器 及 APB1预分频器 分频后,再经过 TIM2,3,4 Multiplier倍频器 倍频,作为 通用定时器的时钟。
  SYSCLK系统时钟 经过 AHB 预分频器 及 APB2 预分频器 分频后,作为 PCLK2时钟 。
  SYSCLK系统时钟 经过 AHB 预分频器 及 APB2 预分频器 分频后,再经过 TIM1 Multiplier倍频器 倍频,作为高级定时器的时钟。
  SYSCLK系统时钟 经过 AHB预分频器 及 ADC预分频器 分频后,作为 ADC时钟。
  主系统时钟大体如下图黄色所示。
  
  
  2.2 细分介绍
  HSE时钟
  HSE :
  High Speed External Clock signal ,即高速的外部时钟。
  来源:
  无源晶振( 4-16M ),通常使用8M。
  控制:
  RCC_CR时钟控制寄存器的位16: HSEON控制。
  
  
  开启HSE的时候,需要一定时间来起振。
  根据RCC_CR时钟控制寄存器的位17: HSERDY 来判断起振是否完毕。
  
  HSI时钟
  HSI :
  Low Speed Internal Clock signal ,高速的内部时钟。
  来源:
  芯片内部,大小为8M,当HSE故障时1系统时钟会自动切换到HSI ,直到HSE启动成功。
  控制:
  RCC_CR时钟控制寄存器的位0 : HSION控制。
  
  控制原理同HSE。
  PLLCLK锁相环时钟
  锁相环时钟:
  来源:
  (HSI/2、HSE)经过倍频所得
  控制:
  CFGR : PLLXTPRE、PLLMUL
  注意:
  PLL时钟源头使用HSI/2的时候, PLLMUL最大只能是16,这个时候PLLCLK最大只能是64M ,小于ST官方推
  荐的最大时钟72M。
  如果需要在应用中使用USB接口,PLL必须被设置为输出48或72MHZ时钟,用于提供48MHz的USBCLK时钟。
  HCLK时钟
  HCLK :
  AHB高速总线时钟,速度最高为72M。为AHB总线的外设提供时钟、为Cortex系统定时器提供时钟(SysTick)、为内核cpu提供时钟( FCLK )。AHB : advanced high-performance bus。
  来源:
  系统时钟分频得到, -般设置HCLK=SYSCLK= 72M
  控制:
  CFGR:HPRE
  PCLK1时钟
  PCLK1 :
  APB1低速总线时钟,最高为36M。为APB1总线的外设提供时钟。2倍频之后则为APB1总线的定时器2-7提供时钟,最大为72M。
  来源:
  HCLK分频得到,一般配置PCLK1=HCLK/2=36M
  控制:
  RCC_CFGR时钟配置寄存器的PPRE1位
  PCLK2时钟
  PCLK2 :
  APB2高速总线时钟,最高为72M。为APB1总线 的外设提供时钟。为APB1总线的定时器1和8提供时钟,最大为72M。
  来源:
  HCLK分频得到,一般配置PCLK1=HCLK= 72M
  控制:
  RCC_CFGR时钟配置寄存器的PPRE2位
  三、其他时钟
  3.1 RTC时钟
  RTC时钟:
  为芯片内部的RTC外设提供时钟。
  来源:
  HSE_ RTC ( HSE分频得到)、LSE (外部32.768KHZ的晶体提供)、LSI(32KHZ)。
  控制:
  RCC备份域控制寄存器RCC_ BDCR : RTCSEL位控制
  3.2 IWDG独立看门狗时钟
  IWDG时钟:
  来源:
  由芯片内部的 LSI RC 提供
  控制:
  略
  其他时钟如下图标号D所示。
  
  四、MCO时钟输出
  MCO时钟输出
  MCO :
  microcontroller clock output ,微控制器时钟输出引脚,由PA8复用所得。
  来源:
  PLLCLK/2 , HSE、HSI、 SYSCLK
  控制:
  CRGR:MCO
  查看下图E。
  
  五、stm32时钟系统的编程
  5.1 系统启动文件的默认时钟配置
  在启动文件中,SystemInit()函数就对系统时钟进行了配置。
  
  
  SystemInit() 后时钟频率大小:
  PLL 主时钟=72MHz
  SYSCLK (系统时钟) =72MHz
  AHB 总线时钟(HCLK=SYSCLK) =72MHz
  APB1 总线时钟(PCLK1+SYSCL K/2) =36MHz
  APB2 总线时钟(PCLK2=SYSCLK/1) =72MHz
  5.2 自定义主系统时钟配置函数
  时钟使能配置函数
  时钟源使能:
   RCC_ HSICmd
   RCC_ LSICmd
   RCC_ PLLCmd
  外设时钟使能:
   RCC RTCCLKCmd
   RCC_ AHBPeri phClockCmd
   RCC_ APBxPeri phCl ockCmd
  设置时钟流程:
  将RCC寄存器重新设置为默认值
  RCC_Delnit
  打开外部高速时钟晶振
  HSE RCC_HSEConfig(RCC_HSE_ON);
  等待外部高速时钟晶振工作
  HSEStartUpStatus = RCC_WaitForHSEStartUp();
  设置AHB时钟
  RCC_HCLKConfig;
  设置高速APB时钟
  RCC_PCLK2Config;
  设置低速速APB时钟
  RCC_PCLK1Config
  设置PLL,主要通过修改PLL的倍频系数改变系统时钟
  RCC_PLLConfig
  打开PLL
  RCC_PLLCmd(ENABLE);
  等待PLL工作
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  设置系统时钟
  RCC_SYSCLKConfig
  判断是否PLL是系统时钟
  while(RCC_GetSYSCLKSource() != 0x08)
  代码:
  #include “stm32f10x.h”
  /*******************************************************************
  *函数:void RCC_HSE_Config
  *功能:通过修改pll的分频、倍频系数改变系统时钟
  *输入:
  u32 div, HSE的分频系数1-2:RCC_PLLSource_HSE_Div1、RCC_PLLSource_HSE_Div2
  u32 pllm, HSE的倍频系数2-16:RCC_PLLMul_2、RCC_PLLMul_3、、、RCC_PLLMul_16
  *输出:
  *特殊说明:
  *******************************************************************/
  void RCC_HSE_Config(u32 div,u32 pllm)
  {
  RCC_DeInit(); //将外设RCC寄存器重设为缺省值
  RCC_HSEConfig(RCC_HSE_ON); //开启外部高速晶振(HSE)
  if (RCC_WaitForHSEStartUp()==SUCCESS) //等待HSE起振
  {
  RCC_HCLKConfig (RCC_SYSCLK_Div1) ;//设置AHB时钟HCLK,1分频。HCLK==SYSCLK
  RCC_PCLK1Config(RCC_HCLK_Div2) ;//设置低速AHB时钟PCLK1,2分频。PCLK1==1/2HCLK
  RCC_PCLK2Config (RCC_HCLK_Div1) ;//设置高速AHB时钟PCLK2,1分频。PCLK2==HCLK
  RCC_PLLConfig (div, pllm) ;//设置PLL时钟源及倍频系数
  RCC_PLLCmd (ENABLE) ; //使能PLL
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //检查指定的RCC标志位设置与否,PLL就绪
  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟SYSCLK来源 设置来源为PLL
  while (RCC_GetSYSCLKSource() !=0x08) ; //返回用作系统时钟的时钟源,0x08:PLL作为系统时钟
  }
  }
  int main(void)
  {
  RCC_HSE_Config(RCC_PLLSource_HSE_Div1,RCC_PLLMul_5);
  while(1)
  {
  }
  }
  我们使用软件仿真观察实验现象。
  进入仿真调试后,打开Power,Reset and Clock Control
  
  可以观察到默认的时钟配置。由图观察到 PLLMUL为7:PLL Clock*9。SYSCLK=9 * OSC=9 * 8=40.
  
  运行RCC_HSE_Config()之后,观察到 PLLMUL变成了3:PLL Clock*5。SYSCLK=5 * OSC=5 * 8=40.
  
举报

更多回帖

发帖
×
20
完善资料,
赚取积分