左左右学堂 · 课程目录

第33期 一节课讲明白STM32时钟系统

观看B站原视频 · 文稿与高清画面

Hello,小伙伴们,大家好。这里是左左右。这期视频我们来聊一聊STM32F103系列的时钟系统。在STM32程序编写过程中,我们经常会用到HAL_Delay这个函数。

那么STM32是如何实现准确计时的呢?在这里我先问大家这样一个问题:如果我让大家在5秒钟后在弹幕上打1,你们会怎么做?大家肯定会看着手机或者手表去倒计时5秒。如果身边没有任何计时设备,该怎么办呢?我们还有最简单最原始的办法。那就是数数。STM32单片机就是通过计数的方法来实现计时的。

在STM32单片机内部有两个时钟源,分别是频率为40KHz低速内部时钟LSI。和频率为8MHz高速内部时钟HSI。他们可以产生固定频率的脉冲信号。脉冲信号每通过一个周期计数加一。其中低速内部时钟主要是为单片机实时时钟系统,即RTC提供时钟源的。如日历、闹钟、时间戳等,而高速内部时钟主要是给片上外设提供时钟的。

如我们前面学到的GPIO和USART等。周期稳定的脉冲信号才能实现稳定的计数,才能保证计时的准确性。由于内部时钟是采用的RC震荡电路,它的精度并不好,所以,我们一般不用。我们会在单片机外部接两个晶振。分别为8Mhz的高速外时钟,即HSE。和32.768khz的低速外部时钟,即LSE。

由于晶振内部的石英晶体拥有一个非常精确的固有谐振频率,所以,外部晶振的精度极高。这里的RTC时钟源可以是多个中的一个。它可以是40Khz的低速内部时钟。也可以是32.768KHz的低速外部时钟。也可以是高速外部时钟的128分频。这里的分频就是做除法运算。当然,低速内部时钟也并不是一无是处。

它单独给看门狗提供时钟源。这里的看门狗可以把它想象成一个必须在规定时间内被“喂食”的“电子看门狗”。如果主程序因为意外,如程序跑飞、陷入死循环、外部干扰等,而未能按时喂狗,这只狗就会“叫醒”或“重启”整个系统,让系统从一个可知的初始状态重新开始运行。后面的课程我们还会详细讲解看门狗的使用。

视频画面 02:52.4
视频画面 02:52.4 · 1080P 原图 · 查看对应视频

这里有一个基础的认知就可以了。上期视频我们讲过APB1总线的最高时钟频率是36Mhz。APB2总线的最高时钟频率是72Mhz。此时我们外部晶振才8Mhz。

那么,如何才能让APB2达到72Mhz呢?这里就要提到PLL锁相环了。它的作用就是倍频。8Mhz的频率经过PLL锁相环乘9就达到72Mhz了。这里的72Mhz分两路。一路经USB分频器到USB。另一路到系统时钟SYSCLK。这里的SYSCLK的时钟源也有很多。它还可以是外部高速时钟不经过锁相环直接到SYSCLK系统时钟。

也可以是8MHz的内部高速时钟。当然,内部高速时钟也并不是一无是处。它可以给FLITFCLK提供时钟。FLITFCLK的核心作用是为某些必须在所有低功耗模式下都能持续工作的关键模块,提供一个独立、稳定、且始终开启的时钟源。简单来说,它是STM32内部的一个 “永不停息的脉搏”。

8MHz的内部高速时钟也可经PLL锁相环到系统时钟。这里的CSS是时钟安全系统。当HSE失效时能启动HSI,并产生中断,我们可以在中断中编写代码。如实现记录日志、切换模式、尝试恢复等功能。SYSCLK经AHB分频器到HCLK。这里的HCLK就是AHB总线的是时钟。HCLK又产生很多分支。

这里经APB1分频器2分频到达最大的36Mhz。APB1定时器经2倍频达到72Mhz。接着,经APB2分频器1分频到达最大的72Mhz。这里的APB2定时器也是72Mhz。ADC经6倍频达到12Mhz。就是说当APB1外设达到最大36Mhz。APB2外设达到最大72Mhz时。

不管是APB1还是APB2总线上的定时器都是72Mhz,这条分支是AHB总线,内核,内存,DMA提供时钟源的。接着,看这里的FCLK。它的作用就是提供CPU内核的工作时钟。这个分支是滴答计时器。这里是1分频也可以是8分频。这里可以看到STM32的时钟系统非常复杂。它有很多的分支。

所以,又被称作时钟树。那么STM32的时钟系统为什么要做的这么复杂呢?一会儿倍频一会分频的,其实,它是为了满足单片机内部的不同需求。那有人肯定就要问了,直接都弄成72Mhz不就完事了嘛。这样做会造成,功耗的浪费。浪费电不就是浪费钱么。我们打开STM32CubeIDE来看一下。

这里的40khz就是低速内部时钟。8Mhz就是高速内部时钟。这时的外部时钟都是灰色的,我们需要通过这里来设置一下。我们直接将HCLK设置为72Mhz。APB1总线上的外设就达到36Mhz的最快速度l。APB2总线上的外设就达到72Mhz的最快速度了。其实,这期视频我们只要记住高速外部时钟的这两条线路。

和低速外部时钟的这一条线路就可以了。其他用到我还会带大家回来看这个图的,吃多嚼不烂,还有这里为什么是灰色呢?我们只需要打开master clock output这个选项就可以了。这时PA8这个引脚就变绿了。这时的PA8就能当做一根时钟线向单片机外部的其他设备提供时钟源了。

这里再给大家补充两个小的知识点。第一个知识点事72Mhz的频率到底有多快?72M等于72乘以10的6次方。我们都知道频率和周期是互为倒数的关系。这样单片机在使用8M外部晶振的情况下。最快就可以实现72分之一微秒记一次数。是不是很快啊?

另外,一个知识点就是32.768这个数感觉很别扭还难记。低速外部时钟为什么是32.768k赫兹?这是因为2的15次方正好就是32768这个数,也就是32786被2分频15次之后就变成1赫兹了,也就是1次/秒。前面我们说了低速时钟用于日历、闹钟、时间戳等功能。它们最基本的单位不就是秒嘛。

如果大家对hal_delay这个函数的实现过程感兴趣也可以给我留言。感兴趣的小伙伴们多的话,我们下期视频就看看hal_delay源码是如何实现延时的供能的?

好的,今天的视频就到这里了。您的关注,点赞和收藏是我持续更新下去的最大动力。我们下期见。

Hello,小伙伴们,大家好。这里是左左右。这期视频我们来聊一聊STM32F103系列的时钟系统。在STM32程序编写过程中,我们会经常用到hal delay这个函数。

那么STM32是究竟是如何实现准确计时的呢?在这里我先问大家这样一个问题:如果我让大家在5秒钟后在弹幕上打1,你们会怎么做?你们肯定会看着手机或者手表去倒计时5秒。如果身边没有任何计时设备,该怎么办呢?我们还有最简单最原始的办法。那就是数数。STM32单片机就是通过计数的方法来实现计时的。

在STM32单片机内部有两个时钟源,分别是频率为40K赫兹低速内部时钟LSI。和频率为8兆赫兹高速内部时钟HSI。他们可以产生固定频率的脉冲信号。脉冲信号每通过一个周期计数加一。其中低速内部时钟主要是为单片机实时时钟系统RTC提供时钟的。如日历、闹钟、时间戳等,而高速内部时钟主要是给片上外设提供时钟的。

如我们前面学到的GPIO和USART等。周期稳定的脉冲信号才能实现稳定的计数。才能保证计时的准确性。由于内部时钟是采用的RC震荡电路它的精度并不好,所以,我们通常不把它们作为主时钟源。我们一般会在单片机外部接两个晶振。分别为8兆赫兹的高速外部时钟HSE。和32.768 K赫兹的低速外部时钟LSE。

由于晶振内部的石英晶体拥有非常精确的固有谐振频率,所以,外部时钟的精度极高。这里的RTC时钟源可以是三选一。它可以是40K赫兹的低速内部时钟。也可以是32.768K赫兹的低速外部时钟。还可以是高速外部时钟的128分频。这里的分频。简单理解就是做除法运算。当然,低速内部时钟也并不是一无是处。

它单独给看门狗提供时钟源。这里的看门狗可以把它想象成一个必须在规定时间内被“喂食”的“电子看门狗”。如果主程序因为意外,如程序跑飞、陷入死循环、外部干扰等,而未能按时喂狗。这只狗就会“叫醒”或“重启”整个系统,让系统从一个可知的初始状态重新开始运行。后面的课程我们还会详细讲解看门狗的使用。

这里有一个基础的认知就可以了。上期视频我们讲过APB1总线的最高时钟频率是36兆赫兹。APB2总线的最高时钟频率是72兆赫兹。此时我们外部晶振才8兆赫兹。

那么,如何才能让APB2达到72兆赫兹呢?这里就要请出PLL锁相环了。它的核心作用就是倍频。8兆赫兹的频率经过PLL锁相环乘9就达到72兆赫兹了。这里的72兆赫兹信号分两路。一路经USB预分频器到USB。另一路则通向系统时钟SYSCLK。这里的SYSCLK的时钟源有多种选择。

它还可以是外部高速时钟不经过锁相环直接到SYSCLK系统时钟。也可以是8兆赫兹的内部高速时钟。当然,内部高速时钟也并不是一无是处。它可以给FLITFCLK提供时钟。FLITFCLK的核心作用是为某些必须在所有低功耗模式下都能持续工作的关键模块。提供一个独立、稳定、且始终开启的时钟源。

简单来说。它是STM32内部的一个 “永不停息的脉搏”,这里的CSS是时钟安全系统。当HSE失效时,它能自动切换到 HSI 并产生中断。我们可以在中断中编写代码。如实现记录日志、切换模式、尝试恢复等功能。这为高可靠性应用提供了保障。SYSCLK经AHB预分频器到HCLK。

这里的HCLK就是AHB总线的时钟。HCLK又产生很多分支。一路经APB1预分频器2分频到达最大的36兆赫兹。这里有一个关键机制。只有当 APB 预分频系数大于1时。比如,这里的2分频,连接到该总线上的定时器时钟。才会在 PCLK1 的基础上被自动倍频乘以2,从而达到最高 72兆赫兹。

另一路经APB2预分频器1分频到达最大的72兆赫兹。这里的APB2定时器也是72兆赫兹。ADC经6倍频达到12兆赫兹。就是说当APB1外设达到最大36兆赫兹。APB2外设达到最大72兆赫兹时。不管是APB1还是APB2总线上的定时器都是72兆赫兹,这条分支是为AHB总线,内核,内存,DMA提供时钟源的。

视频画面 05:06.1
视频画面 05:06.1 · 1080P 原图 · 查看对应视频
视频画面 05:32.8
视频画面 05:32.8 · 1080P 原图 · 查看对应视频

接着,看这里的FCLK。它的作用就是提供CPU内核的工作时钟。这个分支是滴答计时器。这里是1分频也可以是8分频。我们熟悉的hal_delay这个函数就是靠滴答定时器来实现的。这里可以看到STM32的时钟系统非常复杂。它有很多的分支。因此也被形象地称为“时钟树”。

那么STM32的时钟系统为什么要做得这么复杂呢?一会儿倍频一会儿分频的,这都是为了精确满足单片机内部不同模块对时钟速度和功耗的多样化需求。那有人肯定就要问了。直接都弄成72兆赫兹不就完事了嘛。这样做确实简单。但会造成巨大的功耗浪费。对于嵌入式设备。尤其是电池供电的产品来说。

功耗就是续航。省电就是省钱。下面,我们打开S T M 3 2 Cube IDE来直观感受一下。这里的40 k 赫兹就是低速内部时钟。8兆赫兹就是高速内部时钟。这时的外部时钟都是灰色的,我们需要在这里激活它们。我们直接将HCLK设置为72兆赫兹。APB1总线上的外设就达到36兆赫兹的最快速度了。

APB2总线上的外设就达到72兆赫兹的最快速度了。大家只要重点记住 高速外部时钟HSE的主干路径,以及低速外部时钟 LSE 通往 RTC 的这条路径就够了。其他的分支,我们会在后续用到时再回来看这张图。毕竟贪多嚼不烂,还有这里为什么是灰色呢?我们只需要打开master clock output这个选项就可以了。

视频画面 07:19.8
视频画面 07:19.8 · 1080P 原图 · 查看对应视频

这时PA8这个引脚就变绿了。这时的PA8就能当做一根时钟线向单片机外部的其他设备提供时钟源了。这里再给大家补充两个小的知识点。第一个知识点是72兆赫兹的频率到底有多快?72兆等于72乘以10的6次方。我们都知道频率和周期是互为倒数的关系。这样单片机在使用8兆外部晶振的情况下。

最快就可以实现72分之一微秒记一次数。是不是很快啊?另外,一个知识点就是32.768这个数感觉很别扭还难记。低速外部时钟为什么是32.768 k赫兹?这是因为2的15次方正好就是32768这个数,也就是32786被2分频15次之后就变成1赫兹了,也就是1次每秒。前面我们说了低速时钟用于日历、闹钟、时间戳等功能。

它们最基本的单位不就是秒嘛。如果大家对hal_delay函数的底层实现过程感兴趣也可以在评论区留言。感兴趣的小伙伴们多的话。我们下期视频就一起剖析一下hal_delay的源码。看看它是如何实现延时功能的?

好的,今天的视频就到这里了。您的关注、点赞和收藏是我持续更新下去的最大动力。我们下期见。