STM32系列MCU一般来说使用两组时钟源,一组是低速时钟源,一组是高速时钟源。都会分为外部和内部时钟源。Tricore 没有高速低速的分别。一个是外部时钟,一个是内部备份时钟。
时钟源 OSC晶体振荡器,简称晶振,其作用在于产生原始的时钟频率,这个频率经过频率发生器的倍频或分频后就成了MCU中各种不同的总线频率。晶体振荡器 一般高速外部时钟信号HSE(High Speed External Clock signal) 使用OSC晶体振荡器。外部无源晶体与MCU内部时钟驱动电路共同配合形成,有一定的启动时间,精度较高。为了减少时钟输出的失真和缩短启动稳定时间,晶体/陶瓷谐振器和负载电容必须尽可能地靠近振荡器引脚。负载电容值必须根据所选择的晶体来具体调整。
RC选频网络构成的振荡电路称为RC振荡电路,它适用于低频振荡,一般用于产生1Hz~1MHz的低频信号。电路由放大电路、选频网络、正反馈网络,稳幅环节四部分构成。主要优点是结构简单,经济方便。RC需要振荡电路,因此相比OSC来说需要消耗更多的功耗
旁路模式 旁路指的是把MCU内部的起震电路旁路,直接输入占空比为50%的方波、正弦波或三角波。这样外部的器件是可以单独产生时钟信号。
以STM32F407为例,时钟树如上图所示。由于SOC/MCU各个模块是相对独立而又互相联系的单元。独立说的是模块功能独立,例如UART,PWM他们基本上不会互相影响。有联系是指都在一块chip上,由同一个CPU管理。各个模块的速度性能都不太一样,所以他们需要不同频率的时钟来驱动。从而产生树装结构。如果不同频率的器件需要互相沟通,那么就会产生桥(bridge),作用是协调不同速度的外设/模块进行数据通信。 在Tricore上我们可以看到两条总线通过Bridge互通 继续时钟源 LSI (LOW SPEED INTERNAL CLOCK)内部低速时钟源,起主要作用是为独立的 看门狗提供 时钟,有时可以为RTC提供时钟。一般频率为32K。 LSEOSC 外部低速晶体振荡器,频率为32.768,与LSIRC的32K非常接近。为什么是这个频率呢?2的15次方为32786 ,所以对这个时钟进行15的分频,就可以得到1HZ的时钟,周期为1秒。芯片世界和现实世界的时间单位统一了。这个外部时钟主要是产生精确的1秒时钟,为RTC提供精确的频率。RC振荡器非常容易收到温度的影响。 使用独立的时钟有很多的考虑,主要考虑通俗说就是不要把鸡蛋放在一个篮子里。
上面是一对低速时钟,内部称为LSIRC,外部LSEOSC。 那么也会有一组高速时钟。 HSI(Hight speed INTERNAL)F407是16M,F103系列一般是8M。如果外部时钟源还没有稳定,或者没有开启外部时钟源HSE时默认使用内部高速时钟源。STM32遵循CMSIS,启动系统的时候在systeminit中初始化外部高速时钟,如果跳过这个步骤,默认使用内部HSI时钟。 HSE外部高速时钟一般使用OSC晶体振荡器,配合相关的内部,外部电路产生高速的时钟频率。如果如要使用比HSE更高的时钟,需要使用到PLL。所以MCU内部都会有一个PLL产生更多的高速时钟。PLL简单说就是通过一系列乘除运算,把Fosc频率线性放大,乘除的系数称为倍频分频因子。把这部分进行抽象当做一个模块来说就是K*Fosc。
时钟树的结构在STMcube上有非常清晰的结构 使用内部时钟源HSI,高速总线上的设备为16M CLK 。 如果对其分频,该节点后时钟树上的频率为8M
如果使用外部高速时钟源直接输入,那么最大的CLK就是HSE。 那么CPU上百M的频率是怎么来的
HSE可以作为PLL的输入,PLL对时钟进行倍频后就可以产生很高的时钟频率。这是高频率的时钟的来源。通过PLL的系数可以调节PLL输出的时钟频率。 SYSCLK 的来源可以选择三个来源,HSI,HSE,PLLCLK。 从该节点开始有三个分频器,AHB分频器,SYSCLK -->HCLK作为高速总线的时钟频率。APB1,APB2各自都有一个分频器。 RCC clock configuration register 配置以上的分频因子,AHB,APB1,APB2
PLL的部分会稍微复杂一些 图中 有 * / 两个符号,表示乘和除 所以公式就是N/(MP),PLLCLK =( PLL source ) N/(M*P) PLL source可以选择为HSE,HSI 这样这个时钟树的配置就非常清晰了。 RCC PLL configuration register 配置PLL的分频系数 在CMSIS的systemInit函数中对时钟配置,这部分大多数处理器的时钟设定也是这样
首先会ENABLE,HSE外部时钟,等待外部时钟的稳定,应为OSC起震需要时间。HSE稳定是由硬件判断,稳定后硬件置位相应寄存器。
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
接着对AHB,APB1,APB2分频因子配置。 然后对PLL的乘法,除法因子进行配置 然后开启ENABLE PLL 等待PLL锁相环稳定。 稳定后把PLL设置为系统时钟system clock时钟源
再来看一款MCU的时钟树 infineon aurix tc27x PLL产生高于OSC外部时钟源的时钟频率,等待切换完成。 AURIX的PLL设置相比STM32要负责一些,文档对于上面的参数设定解释的很详细,这里不在解析各个参数含义。通俗说就是Fosc的乘除运算。 Tricore和STM 32的PLL配置方式一样。
Fosc相当于HSE,经过PLL的倍频后产生Fpll这个时钟按照STM32的做法是提供给后续高速设备的时钟源。 时钟管理单元CCU接收来自PLL的时钟和备份时钟,还有fosc。 也就是说,CCU的时钟来源和STM差不多。备份时钟可以看做STM32的内部时钟,集成在MCU片上,当外部时钟出现问题或者还没有稳定的时候能够为MCU提供时钟。显然CCU是各组时钟的一个中心处理单元。 这张图说的非常清楚,最左边一列CCU OUTPUT意思是CCU输出的时钟有很多组各种外围模块的时钟频率。当然每个模块还可以对这个输入时钟分频,使得各个模块更加的灵活。列表右边表示CCU输出的时钟来源,默认都是使用Back_up时钟,所以上电后使用的是备份时钟,也就是内部时钟。OSC_XTAL是不可以直接使用的,AURIX对外部的时钟不怎么放心一定要自己过一哈,毕竟aurix安全性高。 Fsri是一条总线时钟,STM32 ARM cortex M3的结构类似,挂载到sri总线上的设备可以使用。后面各个模块可以使用PLL时钟源经过CCU加工后提供给各个模块。Fsri,Fspb和cortex AHB,APB的概念非常相识。 aurix的时钟源,内部BackUp时钟,外部XTAL时钟作为时钟源。经过SCU产生各组时钟,提供给相应外围使用。
|