)
1. 时钟1.1 CPU你有没有想过• 你的 ARM-CPU 能从 Flash 上读取代码并执⾏可是是谁让 ARM-CPU 读取指令的• 你的 ARM-CPU 能⼀直从 Flash 上读取代码并执⾏可是是谁⼀直让 ARM-CPU 读取指令的警察能抓坏⼈( CPU 能执⾏指令)但是是谁让警察抓坏⼈的任何计算机系统包括单⽚机• CPU 也要被驱动。 CPU 很聪明可以读取指令分析指令执⾏指令周⽽复始CPU也很傻它必须在别⼈的催促下才能完成上⾯的⼯作• 这⾥“催促” CPU 运⾏的硬件机制叫做时钟这⾥我们引出了⼀个概念时钟。• 时钟类似⼀个节拍器以固定的频率给设备发送电信号催促⽬标设备进⾏⼯作• CPU 不会主动执⾏需要在时钟这个外⼒的驱使下才能进⾏⼯作我们可以把时钟形象地想象成一个指挥官。1.2 ⽚上外设在 MCU 内部除了 ARM-CPU ,还有其他⽚上外设其他⽚上外设⾃⼰能主动⼯作吗不能。 结论• 单⽚机内部⼏乎所有外设都不会主动⼯作• 他们全部都要在时钟的驱使下进⾏⼯作✨ 结论• 在硬件层⾯上所有的设备包括 CPU 或者外设都要在时钟的推动下统⼀步调进⾏⼯作1.3 时钟开始⼯作下⾯例⼦是⼀个简单的⽰意图虽然真实情况会复杂很多但是我们可以通过该例⼦简单理解时钟 的作⽤• 假设我们所有的设备在硬件特性上设计的时候都是收到⾼电平它才⼯作(尽管事实会有差别)我们⽣成的⾼低电平(时序)叫做时钟信号• 产⽣这部分⾼低电平时序的源头硬件我们叫做时钟源✨ 结论⼀• 有了时钟所有设备都会在统⼀时钟的节奏下步调⼀致且有节奏的进⾏执⾏⼯作1.4 成本敏感下⾯是⼀段单⽚机设计者的⼼理路程我是⼀款单⽚机的设计者我⾃⼰⼼⾥清楚单⽚机上未来会有很多的设备(包括 CPU 和其他⽚上外 设)但是这些外设不⼀定都会被将来的开发者同时使⽤如果开发者⽤不到某些设备还让这些 设备在时钟的催促下做着⽆效的⼯作这样不就是⽩⽩浪费电⼒吗这样的话我设计出来的单⽚ 机功耗肯定⾼功耗⾼变相的不就是使⽤我的单⽚机的成本⾼, 那我设计的单⽚机在市场上 就没有竞争⼒了啊⽽且还要满⾜⽤⼾⾃由选择⽚上外设是否需要使⽤的场景。 那么怎样能保证功耗和功能两者兼顾既要⼜要呢所以可以在设计单⽚机和各种⽚上外设的时候让每个设备处理时钟信息变成可以设置使能的 不就好了这样的话• 我在使⽤任何外设之前都是先使能它的时钟本质就是开启该外设对时钟的受理• CPU 都要受理时钟因为代码要⼀直执⾏⼀般不需要使能• 这就是为什么我们要使⽤任意⼀个⽚上外设的时候需要先开启时钟的原因• 所谓的时钟⽅波本质就是⾼低电平画出来就是⽅波的样⼦1.5 时钟频率有了上⾯的初步理解我们现在有⼀个初步的概念时钟信号的表现形式就类似下⾯的⽅波时序图⽽不同的设备有的当收到上升沿⼯作有的收到下降沿⼯作。这样就可以达到⽤⽅波时序控制设备沿着⼀定的节奏共同⼯作时钟⽣成的⽅波密集设备就⼯作的快时钟⽣成的⽅波疏松设备就⼯作的慢(当然不同设备都有⾃⼰不同的⼯作节奏这个我们后⾯说)。换句话说要理解时钟⽅波还有⼀个⻆度我们必须覆盖到的就是时钟输出快慢的问题。✨ 时钟频率是衡量时钟快慢的指标。时钟频率 是指数字电路中时钟信号每秒输出的完整周期数单位为 赫兹 Hz先别扯什么 Hz 问题什么叫做时钟的⼀个完整周期啊时钟周期周期表⽰重复出现的最⼩完整动作对应的时间单元注意周期是时间单位• 时钟周期特指⼀次完整的波动所需要的时间这⾥的波动就是指 起始状态-变化-回到起始状态 的过程表现形式就是⼀定要有⼀次⾼电平⼀次低电平⽆论⼀个周期 图画成什么样⼦⼀个周期描述的是⼀次波动⼀个波动就是 初始状态-变化-回到初始状态 的过程所以⼀个周期就必然有且只有有⼀个上升沿(变化)⼀个下降沿(回到初始状态)✨ ⼀个周期⼀定要有⼀个上升沿⼀个下降沿。⽽输出⼀个周期是需要花时间的假设是1ms那么 1S 内能输出多少个周期呢 1S/1ms 1000次 。✨ 我们把每秒输出多少个周期数叫做时钟频率次数单位赫兹( HZ )1.6 倍频与分频前⾯为了⽅便我们认为所有的⽚上设备都是⼯作在⼀个时钟源对应的⼀个时钟节奏下可事实 上不同的设备⼯作频率是不同的即需要的时钟频率是不同的。下图是我⽤ AI ⽣成的 STM32F103ZET6 常⻅的外设的⼯作频率清单这是不同外设工作时的时钟频率这些外设我们不懂暂时也不需要懂我们只看到了他们的⼯作频率确实是不同的。✨ 为什么外设的⼯作频率会不同• 硬件⼯艺• 功耗与散热• 通信协议• 精度要求• 等等理由这些知道就可以可是现在我们的设备⼯作都是在⼀个频率下怎么保证让不同的设备在不同的频率下⼯作呢• 给每⼀个设备搞⼀个时钟源不现实功耗⾼设备间同步是个⼤问题• 倍频与分频⼏乎所有的单⽚机选择的做法。倍频: 设计⼀套硬件电路增加时钟频率其实就是输⼊ 1 个时钟周期(就是⼀对⾼低电平)转换输出成为 n 个时钟周期• 倍频器Frequency Multiplier是⼀个⾮常基础且重要的混合信号电路它的核⼼功能是将⼀个输⼊的低频时钟信号转换成⼀个频率更⾼、且波形节奏完全对应的输出时钟信号。• 常⻅的倍频器⽐如锁相环( PLL, Phase-Locked Loop )分频: 设计⼀套硬件电路减少时钟频率其实就是输⼊ n 个时钟周期(就是 n 对⾼低电平)转换输出成为 1 个时钟周期、• 什么叫做分频器分频器Frequency Divider是⼀个⾮常基础且重要的数字电路它的核⼼功能是将⼀个输⼊的⾼频时钟信号转换成⼀个频率更低、但波形完全同步的输出时钟信号。有了倍频和分频的硬件电路设备那么如何⽤⼀个时钟控制源控制不同的设备让他们统⼀步调并且 以不同的频率⼯作呢这样我们就可以⽤⼀个时钟控制源控制不同的设备让他们统⼀步调并且以不同的频率⼯作了。✨ 时钟的本质• 时钟是决策单⽚机⽚上外设什么时候⼯作的设备对单⽚机来讲时钟是发起者。• 其他⽚上外设是执⾏者⼤家在时钟的指挥棒下有序的⼯作• CPU(Cortex-M3) 是未来执⾏代码的地⽅但是也要在时钟的驱使下进⾏取指令、分析指令、执⾏指令的步骤在这⾥ CPU 和⽚上外设并⽆本质区别。1.7 硬件时钟源1. **X18MHz 高速外部晶振 HSEOSC_IN / OSC_OUT引脚 23、24**- 作用给主系统时钟提供原始时钟STM32 内部 PLL 倍频用来驱动内核、串口、定时器等大部分外设。2. **X232.768KHz 低速外部晶振 LSEPC14-OSC32_IN / PC15-OSC32_OUT引脚 8、9**- 作用专门给 RTC 实时时钟供电32.768KHz 正好 2 的 15 次方分频后得到 1 秒计时待机模式下也可以继续跑。细节区分⼀下概念时钟源和时钟信号• 时钟源是“产⽣或提供时钟的硬件实体”时钟信号是“这个实体最终输出到电路中的电信号波形”。2. 时钟树2.1 像单⽚机硬件⼯程师⼀样思考有了关于时钟的宏观认识之后我们现在已经能⼤致理解时钟的作⽤时钟周期的概念更重要的 是⼤致知道不同设备是如何在同⼀个时钟源下⽤不同的频率⼯作⽽且还能进⾏开关使能了。现 在我们继续站在单⽚机设计者⻆度考虑如下推测• 如果只有⼀个时钟源万⼀这个时钟源因为极端情况(⾼温线路⽼化等)⽽⽆法正常⼯作那么整个系统都会瘫痪是的所以 STM32F103 系列的单⽚机不能只有⼀个时钟源具体⼏个取决于设计 • ⽚上外设的⼯作频率是不同的时钟会存在多个虽然可以倍频/分频来满⾜不同⽚上外设的⼯作频率要求但是不同的时钟源⾃⾝频率最好有差别这样在覆盖更⼤的频率范围的同时还会让系统功耗更低功耗低不是因为频率有差别⽽是因为——在不需要⾼频的时候可以选择低频时钟源来⼯作从⽽ 降低功耗。⾼速路双向8⻋道能满⾜交通要求在⼩区⾥⾯修双向8⻋道这种⽅法肯定也能满⾜交通要求但 是没必要这样成本太⾼了。其实还有⼀个精度的考量✨ 所以我们推测• STM32F103 可能会需要多种时钟源• STM32F103 不同的时钟源频率不同• 既然可以有多个时钟源我可以给每⼀个⽚上外设都搞⼀个时钟源其中每⼀个时钟可能既要针对不同的设备进⾏使能还要分频倍频这样的话不就让 MCU内部电路出现了⼤量重复的电路设计吗重复就意味着成本增加单⽚机MCU是成本敏感的设备 这样肯定是不⾏的 所以我们要把时钟功能单独设计⼀套硬件电路⿊盒式的对外提供特定频率的时钟这套硬件电路 叫做时钟树我们把之前的图逆置⼀下就是⼀棵树形结构未来的时钟源就是树根这个时钟源可以有多个⻢上就说• 真实 stm32F103 系列的 MCU 关于时钟树肯定更复杂但是⽆⾮就是对绿⾊区域的部分进⾏重新设计2.2 时钟树结构认识上⾯的时钟树看起来很复杂但是最重要的功能包括最核⼼的特性我们之前已经⻅到过了• 时钟源不⽌⼀个• 要有分频和倍频功能• 要有使能开关 不要被这张图吓到且看我们如何拆解。一共有四个时钟源H是高速L是低速E是外部I是内部我们暂且不关⼼相关细节只需要知道未来可以从这四个硬件处得到最原始的脉冲信号。但是现 在必须搞清楚这四个原始时钟来源在什么位置.2.2 要有分频和倍频功能上图中我⽤蓝⾊⽅框选中的区域都是典型的分频和倍频功能• 只具有⼀个功能的,⽐如 /2 之类的都是固定的分频系数• 其他分频器内部包含了多个系数⽐如 /1,2,4,5,16 等都是⽀持软件动态配置的• 常⻅的倍频器⽐如锁相环( PLL, Phase-Locked Loop )⾄于图中还有很多矩形区域圆圈圈出来的区域都是⼀个⼀个的选择器复⽤器只要知道输⼊有多个信号源选择器可以选 择其中⼀个信号源作为⾃⼰的输出即可。这些后⾯在软件上都是可以配置的。2.2.3 要有使能开关2.3 时钟树理解在我们清楚了时钟树的基本元素构成了那么下⾯需要我们理解时钟树本⾝了上⾯的图略显复杂 其实整颗时钟树我们可以分为三部分• 第⼀部分是时钟树最核⼼的内容负责MCU内部⼤部分设备的驱动⼯作• 第⼆部分主要是低频时钟来进⾏驱动RTC和看⻔狗• 第三部分主要是⽤来进⾏时钟输出的 ⽬前我们很⻓⼀段时间只关注第⼀部分即可其余我们后续专题再说。2.3.1 第⼀部分这部分是时钟树的最核⼼部分也⽐较复杂也是和⽚上外设强相关的这部分搞清楚了时钟树就 理解⼀⼤部分了下⾯我们将第⼀部分进⾏⾼度简化我们的板⼦上选择的外部 HSE 频率是 8MHz• 其实本质上时钟树是⼀颗由 HSE 或者 HSI 作为发⽣源从⽽扇状式的形成不同频率的时钟的⽅式• 狭义上讲HSE、HSI、LSE、LSI在硬件⼯程师⻆度就是时钟源。• ⼴义上讲由 HSE、HSI、LSE、LSI 经过分频倍频形成的 PLLCLK、SYSCLK、FCLK、HCLK、PCLK1、PCLK2 在我们软件⼯程师的视⻆也可以叫做时钟源• 软硬兼有的视⻆你可以把 HSE、HSI、LSE、LSI 叫做“原始时钟来源”⽽由它们经过分频倍频形成的 PLLCLK、SYSCLK、FCLK、HCLK、PCLK1、PCLK2 也能叫做时钟源。• 后续具体说的“时钟源”是哪⼀个我们结合语境来理解。• 我们单⽚机上的 CPUSRAM 和⼏乎所有的⽚上外设⽐如GPIO都是通过这棵树来进⾏时钟驱动的。下⾯我们重点来了解⼀些最常⻅的时钟下⾯问题需要现场解决✨ 练习• 如果我要形成 SYSCLK 是 72MHz 频率的时钟都有多少种⽅式• 如何⽤ SYSCLK 作为时钟源形成 PLLCLK、FCLK、HCLK、PCLK1、PCLK2 需要的时钟频率经过上⾯的学习现在我们已经能理解第⼀部分的构成了我们在回到之前的图中再看就能看懂关于这部分还有最后⼀个问题我们曾经预测过✨ 如果只有⼀个时钟源万⼀这个时钟源因为极端情况(⾼温线路⽼化等)⽽⽆法正常⼯作那 么整个系统都会瘫痪所以我们发现上⾯最核⼼的时钟树的第⼀部分最核⼼的“原始时钟来源”有两个那就是 HSI 和 HSE 都是⾼性能⼀内⼀外。因为这部分都是驱动⽐如 CPU SRAM 各种⽚上外设的所以 频率要求⼀般都是 某MHz 频率的。STM32F103 系列的 MCU 默认使⽤的是 HSI 作为起始“原始时钟来源”来驱动⼤部分MCU设备⽽最佳实践是我们⼀般选择 HSE 作为原始时钟来源因为它精度够⾼。但是如果万⼀使⽤过程中HSE异常了那么时钟树会⾃动切换使⽤ HSI 作为替补原始时钟来源”⽽这个切换⼯作是由时钟树中第⼀部分的⼀个叫做 CSS 的硬件单元完成的.CSS会在主时钟瘫痪以后启动HSI作为保护时钟进行提供频率CSS 的全称 Clock Security System 时钟安全系统它由如下特性✨ HSE 故障 → ⾃动切到 HSI STM32F103 的时钟安全系统 CSS ⼀旦检测到 HSE 失效⽆论 HSE 是直接做SYSCLK 还是经 PLL 硬件会⽴即• 关闭 HSE 及 PLL• 把 SYSCLK 强制切换到 HSI 8 MHz 这个过程完全由硬件完成软件来不及⼲预但会产⽣ NMI 中断供后续补救 HSI 故障 → 不⾃动切到 HSE• HSI 是内部 RC 振荡器规格书⾥不存在“ HSI 失效检测”与“⾃动切到 HSE ”的机制。如果 HSI 因意外停振系统只能死机或复位。因 此只有 HSE 故障时 MCU 才会⾃动降级到 HSI 若想反向保护需要软件⾃⼰写监控逻辑。有了 CSS 就可以在⼀定程度上避免 MCU 出现 HSE 停振导致设备都不运⾏带来的⻛险下⾯给⼀个例⼦ 在⼯业、汽⻋等对可靠性要求⾼的场景 HSE ⼀旦停振 PLL 和 SYSCLK 会⽴刻丢 失 CPU 、外设、通信全部停摆 CSS 能在毫秒级把时钟切到内部 HSI8 MHz ⾄少让 MCU 继续运⾏并有机会上报故障或安全停机避免设备失控3. 时钟树与总线设备结构打通理解下⾯我们已经理解完毕时钟树了后⾯我们在 STM32CubeMx 中会⻅到时钟树中的选择器倍频分频器等是可以配置的。箭头指向的区域只是为了说明时钟树可配置。那么下⾯我们是时候对时钟树进⾏第⼀次总结下图是我们之前学习的总线与设备结构图描述的是各种 MCU 设备是如何在 MCU 内部组织的注意• 因为 STM32F103 MCU 内部是意法半导体内部封装的 Cortex-M3 内核内部电路和⽚上外设的布线⽅式并没有完全披露为了让我们深刻理解 MCU 内部时钟树和外设的关系我们提出来⼀种⾛线⽅式帮助我们构建出⼀套宏观认识• 这也是没有办法的事情官⽅没有披露如果不这样讲我们就⽆法深刻理解时钟树和外设的关系那么也就⽆法建⽴清晰认知3.1.1 总线的理解先统⼀⼀下概念• 这⾥不管什么 ICodeDCodeSystemAHBAPB 总线等它们的硬件本质是⼀样的后⾯解释• 总线不是只有⼀根线ok下⾯我们来介绍⼀下对于⼤部分计算机系统总线不是⼀根线⽽是⼀堆线簇说⼈话就是很多根线合起来叫做总线。⽽总线内部⼀般分为三类:1. 地址总线 - 表明去哪⾥, 读的时候表⽰从哪⾥读。写的时候表⽰写到哪⾥。2. 数据总线 - 表明具体数据3. 控制总线 - 控制什么时候读什么时候写是否完毕是读还是写等与控制逻辑有关的内容就 STM32F103 系列来说因官⽅并未批量相关具体总线数量我们按照32根来进⾏设计1. 地址总线 - 按照 32 根算2. 数据总线 - 按照 32 根算3. 控制总线 - 多少根⽆法确定我们就定成若⼲根吧其中地址总线、数据总线、控制总线合起来才叫做总线。注意• ⽆论是 AHB 总线还是 APB1 APB2 总线还是 IBUS DBUS 等都是上⾯的结构• 其中我们把时钟线(CLK)和读写⽅向线设计到控制总线内部3.1.2 外设寄存器没错寄存器不⽌ CPU 内部存在外设中也是存在的(⽐如之前讲的 GPIO ) STM32F103 上不同 ⽚上外设上⾯的寄存器种类都可能是不同的但是⼤体上我们可以理解成为如下⼏类• 数据寄存器• 控制/配置寄存器• 状态寄存器• ...... ✨ 注意• 我们所列的是⼀般分类不同的外设会有所增加具体取决于外设• 现阶段我们的重⼼应该放在理解宏观结构上后续谈具体⽚上外设在进⾏对应补充即可所以读写数据本质是把数据写⼊到⽬标⽚上外设的寄存器中(⽐如 GPIO )下⾯我们做⼀个⽰意 图说明⼀下过程假设 CPU 要执⾏⼀⾏指令代码块*(uint32_t *)0x4001100C 10;上图是⼀张⽰意图只为了说明原理。3.1.3 结合时钟树与总线设备读写数据线、地址线在设备间也是连接的此处我们简化重点落在时钟线上• 因为意法公司并没有披露 MCU 内部的详细电路图所以上图只是⽰意图协助我们理解时钟树和 总线设备拓扑结构的关系• ⽚上外设我⼿动绘制了⼀个开关每个⽚上外设⼀个这个开关就是时钟树中下⾯的开关 • 这个开关就是我们未来通过代码使能的开关逻辑上就有了3.1.4 CPU 操作⽚上外设的过程时钟线知道怎么接⼊了 CPU 写⼊数据到外设从总线层⾯也知道了但是现在的问题是时钟线和 数据读写关系是什么✨ 先输出结论• 设备间⽐如 CPU 和 GPIO 通信的本质是从 CPU 内寄存器和外设寄存器数据互相拷⻉。• 为便于建⽴清晰的访问模型本节先以标准的⽚上外设访问流程作为讨论基线。需特别说明的是CPU对SRAM等内部存储器的访问其过程仅为地址译码与存储单元读写不涉及外设寄存器操作属于另⼀类特殊场景此处暂不展开 理解保存⼀个bit位⽆论什么是 CPU 还是⽚上外设内部如果有寄存器所以我们需要⾸先搞清楚寄存器的⼯作原理 ⽽寄存器由多位构成所以要搞清楚寄存器就必须先搞清楚寄存器中是如何保存 1 个⽐特位的。✨ 注意• 寄存器其实是由若⼲个D触发器构成的但是直接说D触发器对同学们太不友好所以我们先做理论说明如果想了解硬件电路⻆度的寄存器可以看对应的硬件加餐课为了⽅便画图我们以 8 位寄存器为例虽然 STM32F103ZET6 是 32 位的不⽤担⼼学习完毕本⼩结就可以平滑的理解它了。下图是⼀个可以保存⼀个⽐特位数据的存储单元(第⼀性要做为⼀个存储单元它需要三种功能✨ 1. 写⼊2. 读取并且读取完毕存储单元内的数据还要在可以理解成为拷⻉3. 保持当下次写⼊到来之前存储单元的数据保持不变(其实就是锁存功能)我们认为上⾯的存储单元A已经具有上述 3 个功能了。所以存储单元要⽀持这样的功能就必须引出对应的导线,所以它是这样的上图能体现写⼊和读取那么保持怎么体现呢?什么叫做下次写⼊到来之前存储单元的数据保持不 变我怎么知道下次数据到来了答案是存储单元内部需要有⼀个开关写完成之后就直接断开开关直到下次开关闭合才再 次从写端写⼊。也就是说开关闭合就意味着要有新数据到来了。所以继续更新这个⽰意图这样必须满⾜2个条件写端才能把数据写⼊到存储单元A中• 写端有数据⽐如1• 开关闭合在不闭合开关的时候情况下存储单元A内部的数据就要保持⽼的值不变这就是保持功能那怎么闭合开关呢总不能⼿摁触发器吧所以存储单元被设计成为⽤电平来控制开关(具体我 们⻢上说)⼀般⽽⾔✨ 暂时不重要的知识闭合存储单元开关有四种闭合触发⽅式• 上升沿触发• 下降沿触发• ⾼⽔平触发• 低⽔平触发ok现在我们已经能够保存⼀个 bit 位了整体总结就是• 写端有数据⽐如写⼊ 1• 同时给使能端⼀个上升沿闭合开关这样数据就写⼊到存储单元了⽐如我们写⼊1上升沿结束以后开关自动断开我们让他们都要在统⼀的步调下输⼊那么让所有的存储单元使⽤同⼀个使能位• 那么恭喜你你⾃⼰做了⼀个 8 位寄存器 32 位同样如此这样你如果要写⼀个10到寄存器中那么10对应的⼆进制是 0000 1010 假设从上向下依 次是(顺序不重要取决于未来⾛线)⼀个时钟到来 CPU 把数据写⼊到数据总线当然也把数据要去的地址读写⽅向信息也写⼊到对应的总线位置(这个因为篇幅问题没画出来)• 于此同时不考虑分频的情况下⽚上外设的寄存器开关也被使能打开数据就从CPU-总线-外设寄存器了。• 考虑分频也⽆外乎是隔⼏个上升沿再使能读取数据到⽚上外设寄存器、所以可以回答最开始的问题了✨ 时钟线和数据读写关系是什么• 时钟线上⾯的时钟让放数据到总线和开启⽬标设备寄存器同步进⾏。 • 这⾥的同步不⼀定是同时进⾏因为分频的存在这⾥的同步是步调有规律4. RCCRCC 的全称是 Reset and Clock Controller 即复位与时钟控制器。现如今我们已经理解了时钟、时钟树、时钟树和设备总线的关系等等话题从之前的过程来看我 们可以感受到• 时钟树是打散到整个 MCU 内部和总线设备共同布线的• 时钟树中关键的位置⽐如时钟⽣成器选择倍频分频操作使能外设等等都是需要被配置的。之前我们重点在时钟树本⾝上下⾯我们就要过渡到时钟树配置层⾯。当然我们后⾯少不了具体 配置操作现在的重点是理解配置本⾝。要理解这块我们就需要找到突破⼝。4.1 理解开关电路当 输⼊A1 的时候输出与 输⼊B 相同 • 当 输⼊A0 的时候 输⼊B 输⼊⽆效• 这不就是开关吗注意• 开关很多这⾥只是其中⼀种配置存储单元就可以达到使能开关的⽬的• 存储单元如果保存了1那么它就会持续输出1就是开启与⻔开关• 存储单元如果保存了0那么它就会持续输出0就是断开与⻔开关所以通过配置寄存器就可以使能外设的本质是4.3 引出RCC概念⽤⼀堆寄存器来表⽰MCU内部常⻅的配置⽐如时钟⽣成器选择倍频分频操作使能外设 复位设备等等。我们把这种专⻔负责MCU内部整体配置的功能模块叫做 RCC 。RCC 的全称是“ reset and clock control ”字⾯意思就是复位和时钟控制⽬前我们主要 介绍 STM32F10x 系列的时钟和时钟树相关知识暂且先不管什么复位问题。5.1 第⼆部分什么是RTC?RTCReal-Time Clock是 MCU 内部的⼀个⽚上外设核⼼功能是“实时时钟”就是要在 系统断电、重启或 MCU 休眠 的情况下仍然持续、准确地记录“现实世界”的年⽉⽇时分秒。让 MCU 随时知道“现在⼏点”从⽽按时触发事件⽆需⼈⼯重新校准。为什么要有RTC? ⽐如 ⾼速公路 ETC ⻔架计费系统。⻔架在过⻋瞬间要记录⻋牌、通⾏时间并把精确到毫秒的时间戳上传到结算中⼼。若断电 后时间丢失同⼀辆⻋会被漏扣造成跨省对账失败或者纠纷。这个时候就需要摄像头内 MCU 在万⼀断电的情况下也能正常⼯作并记录时间其实是⼀般完整的产品上为了保证 RTC 功能会在 MCU 外部通过 VBAT 引脚外接⼀个纽扣电池如果正常 VDD 供电纽扣电池不⼯作但是⼀旦 VDD 掉电或者关机等纽扣电池会⾃动为 MCU 供电维持 RTC 时间的更新保证最基本的时间同步。• ⼀般我们的笔记本台式机也是如此• VBAT 引脚全称: Voltage Battery 电池电压引脚独⽴看⻔狗 是什么?们的程序烧写到⽚⼦上之后可能会导致程序跑⻜进⽽引起死机如果没⼈按复位键独⽴看⻔狗⾃⼰到时间就把板⼦重启让设备继续⼲活。关于这块内容我们后⾯再详细介绍。ok我们现在知道 RTC 和独⽴看⻔狗就是 MCU 内部的⼀个⽚上外设那么它们和其他设备( USART,GPIO 等)⼀样也要在时钟的驱动下进⾏⼯作。• RTC 内部核⼼其实就是⼀个递增计数器就是MCU启动到现在的秒数记录的就是时间戳• 看⻔狗也是⼀个递减计数器计数器减到 0 就会⾃动重启 MCU 所以我们后⾯编程的时候使⽤看⻔狗就要在⾃⼰的循环代码中不断重置递减计数器到最开始的值这个叫做喂狗。如果⼀直喂狗计数器就不会减到 0 如果程序跑⻜了不再喂狗了计数器就会慢慢减到 0 然后⾃动重启 MCU所以⽆论是RTC还是看⻔狗都是计数器那么他们更新计数器的时间都是秒/毫秒级别的那么就决定了它们是两个慢节奏的设备不需要 MHz 级别的时钟 kHz 级别的就够⽤了所以可以通过配置选择器选择使⽤ HSE、LSE、LSI 中的哪⼀个作为⾃⼰的时钟源发⽣器然后就可以⽣成给 RTC 使⽤的 RTCCLK 时钟源还有给看⻔狗使⽤的 IWDCLK 时钟源。 最佳实践• RTC ⾸选 LSE 32.768 kHz 晶振掉电也能⾛备选 LSI≈40 kHz 或HSE/128 。• IWDG 只能⽤ LSI ≈40 kHz独⽴运⾏不受外部晶振影响。为什么 LSE 是 32.768kHz • 32.768kHz 32768Hz • 未来在学习 RTC 的时候就知道 RTC 这个⽚上外设内部还有⾃⼰的分频器如果选择 LSE作为 RTC 的时钟源那么你暂时认为RTC内部的默认分频系数就是 32768使⽤ LSE 时钟频率 32.768kHz 可以保证向RTC提供⼀个稳定的1S级的时钟进⾏时间戳更新。 如果你⾮要选择使⽤HSE8MHz, 作为时钟源发⽣器那么就需要你重新计算并配置⼀下RTC的预分 频器值了类似下⾯8MHz 8 000 000 Hz分频系数总数 8 000 000 Hz ÷ 128 ÷ 1 Hz 62 500这些未来在RTC部分都是可以设置的看⻔狗原理不做更多解释思想类似5.2 第三部分第三部分在实际⽤途中⽤的⾮常⾮常⾮常少这部分我们也就不在画图解释了但是有⼏点需要点 出来• MCO ( Microcontroller Clock Output ):把 MCU 内部选中的时钟信号 HSI、HSE、PLLCLK 等直接引到某个 GPIO 引脚对外输出时钟信号 • 上图第三部分中的 HSI、HSE、PLLCLK 等时钟是直接⾛线接⼊到前两部分的特定位置标准⽂档并未画出但是我们⾃⼰要理解❓ 最重要的是为什么要输出时钟• 可以给外围的器件提供时钟可以达到同步设备或者节省成本 (MCU MCO 就当成⼀个时钟发⽣器)的⽬的商业板⼦⼏分钱的成本都要节省• 如果不理解就当成测试接⼝来⽤外接⽰波器输出内部时钟信号验证配置信息是否正确。