1. 时钟
什么是时钟呢?
一个可以产生周期性信号的设备
什么是周期性信号?
1 ----- ----- -----0 ----- ----- -----
所以时钟信号就是周期性变化的信号
关于时钟我们有两个比较重要的概念需要理解:
T:时钟周期,最小重复的信号单元的时间长度,基本单位为s(秒)F:时钟频率,1s内有多少个重复的信号单元(1s振动多少次),单位Hz
---> T * F == 1s
例子:
F = 200Hz 意味着 1s 振动 200次
---> 每次振动的时间是 1 / 200 s == 5ms
2. 为什么需要时钟
时钟最主要的作用是用来同步信号用的
什么是同步呢?
就比如我们的左腿和右腿实际上就需要进行同步,两腿需要协同工作,左腿迈一步然后右腿迈一步,依次重复,人就能正常前行。对应在我们的机器上也是一样的,机器的运行是由很多器件协同工作完成的,当一个器件完成分给它的工作时,理应通知别的器件它完成了,轮到你干活了,等你干完我再继续干。类似于左腿迈完步子了,要等右腿迈完左腿再迈。比如:在A和B进行数据的收发时,A发完数据后应该等待B去接收,等B接收完了之后A再继续发,这种就是同步通信
而我们的M4中大部分时序逻辑电路需要同步,那设备之间怎么实现同步?
这就需要用到我们的时钟信号了
设备是怎么根据时钟信号实现同步的呢?来看电路以及时序图:
如上电路图中假设A端和B端的时序变化如下:
理论上A&B端的电平变化应该如上图所示,输出端(A&B)的电平变换应该要与B端的一致,但是实际上却是下面这样:
为什么会有这样的现象呢?主要是因为A和B输入到&门时,输出需要经过一段的反应时间,虽然这个时间比较短。那么在B端电平变化后,不能立马去读取输出端的电平,应该要等待一段时间后再去读取,那么应该要等待多长时间?此时间段实际上是可以获取到的,我们只需要对电路进行如下改动:
电路修改后, C端的电平的变化如下:
很明显,C端的高电平时期就是&门处理数据的时间(记为de_t),这段时间是不正常的,正常情况下C端应该一直是低电平(当&门处理数据没有延时的时候),我们将C端时序中凸起的地方就称之为“毛刺”。“毛刺”时期是不正常的,我们应该要略过它,略过的意思是指当B的信号发生改变时我们不应该立马去读输出值,而是应该等待一段时间,等电路(如:&门)将数据处理完毕后,再去读取输出值此时才是准确的怎么略过?此时就需要用到我们的时钟信号了
当我们在电路中加上REG后,在REG内部的触发器(假设触发器上升沿触发)的作用下,D端的电平变化如图:
通过上面的时序图可以得知,D此时输出的是一条干净的,没有“毛刺”的信号,那么通过上面这种现象我们可以总结出电路中处理“毛刺”的解决方案:
- 输入信号只能在Clock低跳变(下降沿)时改变,在Clock为高电平时保持不变
- T > 2 * de_t (周期必须大于2倍时延)
3. 时钟信号是怎么产生的呢?
在自然界中有一些物体天生就会产生摆动(振动) ---> 石英晶体
如果想利用石英晶体规则地、周期性的产生方波信号,需要一些电路来保证:
晶振电路:频率一般会比较小,如:12M、8M...
但是石英晶振难以满足现代计算机的高频需要,如:CPU它的频率会很高
那么我们就有“分频 / 倍频”电路:
分频:把输入频率变小
倍频:把输入频率变大
比如:在M4中接触的比较多的有PLL:锁相环电路
4. STM32F4xx 时钟树(时钟系统)
查看<STM32F4xx中文参考手册.pdf>第六章(复位和时钟控制)第二节(时钟)第107页可以得到M4的时钟树(见图<时钟树.png>)
时钟树中有几个关键名词:LSI: Low Speed Internal 内部低速时钟 (32 kHz RC振荡器)
LSE: Low Speed External 外部低速时钟 (32.768KHz)
HSI: High Speed Internal 内部高速时钟 (16 MHz RC振荡器)
HSE: High Speed External 外部高速时钟 (8MHz)
内部时钟: 由内部集成的RC震荡电路产生
外部时钟: 由晶振产生通过GEC-M4原理图可知:
HSE_VALUE = 8M(外部高速时钟8M,取决于所接晶振大小)
从HSE出发沿着线路往右边走,会来到SW选择器,选择器一共有三路输入,分别为HSE/HSI/PLLCLK(锁相环时钟),选择这三者之一作为系统时钟来使用,我们的系统时钟最高可以达到168Mhz。很明显HSE/HSI提供不了168Mhz的频率,那么则由锁相环提供
而锁相环的输入是由HSI和HSE二选一之后进行M分频后得到的。在我们M4中我们选择的是HSE,也就是8M进行M分频后输入锁相环
即 SYSCLK = PLLCLK <--- 168M
= (HSE / M) * N / P
= (8Mhz / M ) * N / P
所以PLLCLK是由M和N以及P决定,实际上这三者的值可以在代码中指定:
M ---> 代码中用PLL_M表示 ---> 8分频(根据HSE而来,