在STM32的启动文件中会调用调用固件库函数中的SystemInit(在文件system_stm32f10x.c)来初始化时钟,把时钟初始化为72Mhz,先来看下时钟树的整体图
先看锁相环时钟的设置
我们先看到HSE,什么是HSE,HSE就是High Speed External Clock signal,即高速的外部时钟,它的来源是无源晶振(4-16M),通常使用8M,用RCC_CR时钟控制寄存器的位16:HSEON控制,看到我们的开发板原理图,当使用无源晶振的时候需要用到我们的电容,当使用有源晶振时就只需要IN引脚进入单片机里面
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200308164522381.png
与HSE相对有一个内部的叫HSI,高速的内部时钟,默认为8Mhz,当系统发生故障的时,系统时钟会自动切换到HSI,直到HSE启动成功,用RCC_CR时钟控制及寄存器的位0:HSION控制
看到锁相环,锁相环的作用就是倍频,由倍频因子PLLMUL决定,它的来源可以是内部的HSI的1/2(当使用HSI的时候PLLMUL最大是16,PLLCLK最大只能是64M),也可以是HSE的1/2或者HSE本身(由PLLXTPRE决定),
系统时钟的设置
由图可以直到系统时钟的来源可以是PLLCLK,HSI,HSE,最大为72M,一般的配置是系统时钟等于PLLCLK,经系统时钟出来后会经过AHB预分频器,接着会经过APB1(最大36Mhz),APB2分频器分频后供外设使用(由时钟配置寄存器RCC_CFGR配置)
其中需要理解的是 APB1 和 APB2 的区别, APB1 上面连接的是低速外设,包括电源接口、备份接口、 CAN、 USB、 I2C1、 I2C2、 UART2、 UART3 等等, APB2 上面连接的是高速外设包括 UART1、 SPI1、 Timer1、 ADC1、 ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等
引入的一个还有RTC时钟和看门狗时钟
MCO时钟
通过MCO可以给别的芯片提供时钟,节省晶振,节约成本,还能改善EMI,如下图
MCO引脚在F103系列是PA8
特殊点
时钟安全系统(CSS) 时钟安全系统可以通过软件被激活.一旦其被激活,时钟监测器将在HSE振荡器启动延迟后被使能,并在HSE时钟关闭后关闭. 如果HSE时钟发生故障,HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和 TIM8)的刹车输入端(TIMx_BKIN),并产生时钟安全中断CSSI,允许软件完成营救操作.此CSSI中断连接到 Cortex™-M3的NMI中断(不可屏蔽中断)。
注意:
一旦 CSS 被激活,并且 HSE 时钟出现故障,CSS 中断就产生,并且 NMI 也自动产生. NMI 将被不断执行,直到 CSS 中断挂起位被清除.因此,在 NMI 的处理程序中必须通过设置时钟中断寄存器 (RCC_CIR) 里的 CSSC 位来清除 CSS 中断。
如果HSE振荡器被直接或间接地作为系统时钟,(间接的意思是:它被作为PLL输入时钟,并且 PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡 器被关闭.在时钟失效时,如果HSE振荡器时钟(被分频或未被分频)是用作系统时钟的PLL的输 入时钟,PLL也将被关闭.
最后我们来讲解下文件system_stm32f10x.c中的SystemInit函数
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= (uint32_t)0xFEF6FFFF