最近再把时钟树好好重温一遍,,找到当初遗漏忽略的知识点。
① LSI(Low Speed InternalClock, 低速内部时钟):RC振荡器, 它不同于晶振,晶振是由物理上产生的效果,RC振荡器不是由物理产生,所以它精确度并不是很高, 频率为32KHz 。独立看门狗 的时钟源只能是 LSI ,同时 LSI 还可以做 RTC 的时钟源。② LSE (Low Speed External Clock, 低速外部时钟):接频率为 32.768KHz 的石英晶体, LSE 主 要是 RTC 的时钟源。③ HSI ( High Speed Internal Clock, 高速内部时钟): RC 振荡器,频率为 16MHz ,精度不高, 当HSE的PLL锁相环出现故障,不稳定的时候,没有启动起来的时候,先用一下HSI,起到备用的作用 。④ HSE ( High Speed External Clock, 高速外部时钟):可接石英 / 陶瓷谐振器,或外接时钟源, 频率范围是 4MHz~26MHz。(STM32F407的开发板用的是一个 8Mhz 的晶振)⑤ PLL ( Phase Locked Loop, 锁相环倍频输出): HSI用来备用,HSE频率只有8Mhz太低 , 所以系统主频主要就是来自于PLL, 理论上不能算是时钟源 ,只是接收时钟源后 对其进行分 / 倍频,分 / 倍频倍数可修改参数调节。(STM32F407的开发板最大可输出 168Mhz )
其中 ③ ④ ⑤ 是来驱动系统时钟 (SYSCLK) 的。
1. HSE 高速外部时钟信号可以由有源晶振或者无源晶振提供,频率从 4-26MHZ 不等,我们的开发板使用的是 8MHZ 的晶 振,当HSE 故障时,高速的内部时钟信号 HSI 会作为 备用的系统时钟 , 直到 HSE 恢复正常。2. 锁相环 PLL PLL 的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件,由 HSE 或者 HSI 提供时钟 输入信号。 主PLL 有两路的时钟输出,第一个输出时钟 PLLCLK 用于系统时钟, F407 里面最高是 168M 。 第二个输出用于USB OTG FS 的时钟( 48M )、 RNG 和 SDIO 时钟( <=48M )。 专用的 PLLI2S 用于生成精确时钟,给 I2S 提供时钟。 PLLCLK的计算公式为:VCOCLK_IN = PLLCLK_IN / MVCOCLK_OUT = VCOCLK_IN * NPLLCLK_OUT=VCOCLK_OUT/P3. 系统时钟 SYSCLK系统时钟来源可以是: HSI 、 PLLCLK 、 HSE ,具体的由时钟配置寄存器 RCC_CFGR 的 SW 位配 置。我们这里设置系统时钟:SYSCLK = PLLCLK =168M 。 如果系统时钟是由HSE 经过 PLL 倍频 之后的 PLLCLK 得到,当 HSE 出现故障的时候,系统时钟会 切换为HSI=16M ,直到 HSE 恢复正 常为止。
启动文件
提问:
在main函数里,我们没有调用任何函数修改时钟参数,那么时钟频率被修改后是怎么生效的呢?启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
1. 初始化堆栈指针SP=_initial_sp (堆栈空间初始化)
2. 初始化PC 指针=Reset_Handler (程序运行到哪 PC指针 就指向哪)
3. 初始化中断向量表
4. 配置系统时钟
( SystemInit() 是一个标准的库函数,在system_stm32f4xx.c 这个库文件总定义。主要作用是配置系统时钟。)
5. 调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界
修改系统时钟
总结!!!!!!!!!!!!!!!!!!
总结: 336 / 2 = 168 系统时钟
路漫漫其修远兮,吾将上下而求索。