1.时钟树
1.1 时钟
问:什么是时钟?为什么要有时钟?时钟是怎么产生的?
(1)什么是时钟?
时钟就是具有周期性的脉冲信号,相当于单片机的心脏,给单片机提供一个统一的信号,要想使用单片机的外设必须开启相应的时钟。
对CPU来说,假设CPU在一个时钟周期内执行一条指令,若时钟频率越高,则时钟周期更短,则在相同的时间CPU能够执行更多的指令,CPU的运行速度更快。
(2)为什么要有时钟?
时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而单片机有了时钟,才能够运行执行指令,才能够做其他的处理 (点灯,串口等等其他操作),时钟的重要性不言而喻。
(3)时钟是怎么产生的?
时钟产生比较复杂,方法也有很多种,但它们都是从晶体谐振器(简称晶振)开始的,在石英晶片上加上交变电压,晶体就会产生机械振动,机械形变振动又会产生交变电场,尽管这种交变电场的电压极其微弱,但其振动频率是十分稳定的。(我只能说神奇的物理世界)
1.2 时钟树概述
STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,为了降低整个芯片的功耗,所有外设时钟默认都是关闭状态(disable),当我们使用某个外设就要开启这个外设的时钟(enable)。
不同外设需要的时钟频率不同,没必要所有外设都用高速时钟造成浪费,而且有些外设也接受不了这么高的频率,这也是为什么STM32有四个时钟源(HSE、 LSE、HSI、LSI)的原因,就是为了兼容不同速度的外设。
而51单片机不需要配置时钟,是因为一个时钟开了之后所有的功能都可以用了,而这个时钟是默认开启的,所以51单片机无法做到低功耗。
STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,也是为了降低整个芯片的耗能。时钟树框图见《STM32F4xx中文参考手册》6.2章节
1.3 主时钟树详解
在STM32中,有4个时钟源:
① LSI(Low Speed Internal Clock, 低速内部时钟):RC振荡器,频率为32KHz。独立看门狗的时钟源只能是LSI,同时LSI还可以做RTC的时钟源。
② LSE(Low Speed External Clock, 低速外部时钟):接频率为32.768KHz的石英晶体,LSE主要是RTC的时钟源。
③ HSI(High Speed Internal Clock, 高速内部时钟):RC振荡器,频率为16MHz,精度不高。
④ HSE(High Speed External Clock, 高速外部时钟):可接石英/陶瓷谐振器,或外接时钟源,频率范围是2MHz~26MHz。(我们的开发板用的是一个8Mhz的晶振)
⑤ PLL(Phase Locked Loop, 锁相环倍频输出):理论上不能算是时钟源,只是接收时钟源后对其进行分/倍频,分/倍频倍数可修改参数调节。(我们的开发板最大可输出168Mhz)
注意: 以上频率仅针对STM32F40x,其它的以数据手册为准
其中 ③ ④ ⑤ 是来驱动系统时钟 (SYSCLK)的。
1.3.1 HSE 高速外部时钟信号
可以由有源晶振或者无源晶振提供,频率从4-26MHZ 不等,我们的开发板使用的是8MHZ的晶振,当HSE 故障时,高速的内部时钟信号HSI会作为备用的系统时钟,直到HSE恢复正常。直接作为系统时钟来源或者经过128分频作为RTC时钟来源。使能之后要等待时钟稳定。
1.3.2 HSI高速内部时钟信号
直接作为系统时钟的来源。
1.3.3 LSE低速外部时钟信号
作为RTC时钟来源
1.3.4 LSI低速内部时钟信号
为RTC提供时钟;为独立看门狗提供时钟
2. 锁相环PLL
PLL 的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件,由HSE振荡器或者HSI 振荡器提供时钟输入信号。
输入来源高速外部时钟(HSE)二分频或不分频直接输入;高速内部时钟二分频输入。
主PLL 有两路的时钟输出,第一个输出时钟PLLCLK(78MHZ) 用于系统时钟,F407 里面最高是168M。
第二个输出用于USB OTG FS 的时钟(48M)、RNG 和SDIO 时钟(<=48M)
专用的PLLI2S 用于生成精确时钟,给I2S 提供时钟。
PLLCLK的计算公式为:
VCOCLK_IN = PLLCLK_IN / M
VCOCLK_OUT = VCOCLK_IN * N
PLLCLK_OUT=VCOCLK_OUT/P
3. 系统时钟SYSCLK
系统时钟来源可以是:HSI、PLLCLK、HSE,具体的由时钟配置寄存器RCC_CFGR 的SW 位配 置。我们这里设置系统时钟:SYSCLK = PLLCLK =168M。
如果系统时钟是由HSE 经过PLL 倍频之后的PLLCLK 得到,当HSE 出现故障的时候,系统时钟会切换为HSI=16M,直到HSE 恢复正 常为止。
4. APB2 总线时钟PCLK2
APB2 总线时钟PCLK2 由HCLK 经过高速APB2 预分频器得到,分频因子可以是:[1,2,4,8,16], 具体由时钟配置寄存器RCC_CFGR 的PPRE2 位设置。PCLK2 属于高速的总线时钟,最高可达72MHZ,片上高速的 外设就挂载到这条总线上,比如全部的GPIO、USART1、SPI1 等。
这里设置为2 分频,即PCLK2 = HCLK /2= 84M
5. APB1 总线时钟PCLK1
APB1 的低速总线时钟PCLK1 由HCLK 经过低速APB 预分频器得到,分频因子可以是:[1,2,4,8,16],
具体由时钟配置寄存器RCC_CFGR 的PPRE1 位设置。PCLK1 属于低速的总线时钟,最高为42M(有的教材写是36MHZ),
片上低速的外设就挂载到这条总线上,比如USART2/3/4/5、SPI2/3,I2C1/2 等。
这里设置为4 分频,即PCLK1= HCLK/4 = 42M。
6.RTC时钟
RTC时钟:为芯片内部的RTC外设提供时钟
来源:HSE_RTC(HSE分频得到)、LSE(外部32.768KHZ的晶体提供)、LSI(32KHZ)
控制:RCC备份域控制寄存器RCC_BDCR:RTCSEL位控制
独立看门狗时钟:IWDGCLK,由LSI提供
7.时钟安全系统(css)
监视高速外部时钟HSE的工作状态。若HSE失效,会自动切换,会自动切换高速内部时钟HSI作为系统时钟的输入,保证系统的正常运行。一旦CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并且NMI也自动产生。NMI将被不断执行,直到CSS中断挂起位被清除。
8. MCO时钟输出
9. I2S时钟
I2S 时钟可由外部的时钟引脚I2S_CKIN 输入,也可由专用的PLLI2SCLK 提供,具体的由RCC 时钟配置寄存器(RCC_CFGR) 的I2SSCR 位配置
10. 启动文件
提问:在main函数里,我们没有调用任何函数修改时钟参数,那么时钟频率被修改后是怎么生效的呢?
启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:
1.初始化堆栈指针SP=_initial_sp
2.初始化PC 指针=Reset_Handler
3.初始化中断向量表
4.配置系统时钟
5.调用C 库函数_main 初始化用户堆栈,从而最终调用main 函数去到C 的世界
比如:
Stack_Size EQU 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
开辟栈的大小为0X00000400(1KB),名字为STACK_Size,NOINIT 即使不初始化,可读可写,8(2^3) 字节对齐。
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
SystemInit() 是一个标准的库函数,在system_stm32f4xx.c 这个库文件总定义,主要作用是配置系统时钟。__main 是一个标准的C 库函数,主要作用是初始化用户堆栈,最终调用main 函数去到C 的世界。这就是为什么我们写的程序都有一个main 函数的原因。如果我们在这里不调用__main,那么程序最终就不会调用我们C 文件里面的main。
回到刚刚的问题:在main函数里,我们没有调用任何函数修改时钟参数,那么时钟频率被修改后是怎么生效的呢?
答:既然main函数没有调用,那修改时钟的操作当然是在main函数之前执行的SystemInit()函数设置的了。
针对F4主控板调节系统时钟
- 修改主频到168Mhz
static void SetSysClock(void);
系统时钟计算方式:
- 超频和降频
11.应用场景
调节 CPU 的运行频率,来控制系统的性能与功耗。比较典型的例子就是说手机/笔记本电脑都有高性能模式、平衡模式、低性能模式。
标签:RTC,HSE,--,STM32,单片机,RCC,main,外设,时钟 From: https://blog.csdn.net/qq_53030130/article/details/139815145