Skip to content
清晨的一缕阳光
返回

晶振、时钟周期、机器周期、指令周期与RC振荡电路详解

晶振、时钟周期、机器周期、指令周期与RC振荡电路详解

51单片机的晶振,全称石英晶体振荡器(Crystal Oscillator,简称XTAL)。石英晶体本身是一块二氧化硅薄片,利用压电效应产生稳定周期性振荡,给CPU提供节拍信号,也就是时钟。本文从最底层的物理原理出发,串联起晶振→时钟周期→机器周期→指令周期的完整链路,并对比RC振荡电路的工作机制。


一、压电效应(晶振的物理基础)

石英晶体有个核心物理特性:压电效应,分为正、逆两个方向:

  1. 正压电效应:给石英晶体施加机械压力 → 晶体表面会产生电压。简单说,按压一下,就输出电压。
  2. 逆压电效应:反过来,给石英薄片两端施加交变电压 → 晶体会发生机械形变、振动。

如果给晶体通交变电压,晶体就会来回机械抖动;晶体本身有固定的固有振动频率,只跟晶体切割厚度、形状有关。 比如我们买的12MHz晶振:这块石英薄片的物理尺寸就被加工成,机械振动刚好12,000,000次每秒。

⚠️ 晶体本身不能自己起振!它只是一个选频元件,必须配合单片机内部振荡电路,才能输出时钟。


二、51单片机内部振荡电路(外接晶振模式)

经典8051有两个专用引脚:

外部典型接线方式:

完整工作过程

  1. 单片机上电,内部有一个反相放大器(增益很高),输入XTAL1,输出XTAL2。
  2. 放大器输出接到晶振,给晶振施加交变电压。基于逆压电效应,石英晶体开始机械振动。
  3. 晶体振动,又通过正压电效应,转化回电信号送回放大器输入端XTAL1。
  4. 形成正反馈环路:放大器输出 → 晶振振动 → 电信号回送给放大器输入 → 继续放大振动。
  5. 只有晶体**固有频率(例如12MHz)**的信号,环路满足振荡条件,其他频率直接被过滤衰减掉。 👉 于是环路就稳定输出固定频率:12MHz正弦波信号

两个接地电容的作用:

  • 和晶体构成谐振回路,匹配负载,保证振荡稳定;
  • 微调振荡频率;电容值不对,可能不起振,或者频率轻微偏移。

两种时钟模式区分

模式接法适用场景
外部晶体模式(最常用)XTAL1、XTAL2接晶振+负载电容,单片机内部放大器起振绝大多数单机系统
外部时钟输入模式不接晶振,外部已经生成好的时钟方波直接接到XTAL1,XTAL2悬空多芯片同步时钟、系统级时钟分发

三、正弦波 → CPU可用的方波

晶振环路输出的是正弦波,但CPU是数字电路,不识别正弦波,CPU需要高低分明的方波脉冲。

单片机内部还有一个关键电路:施密特触发器(整形电路),它的作用是: 把正弦波形修整成标准数字方波——高电平/低电平来回跳变。 这个整形后的方波,就是系统时钟(时钟周期信号)。 每一次电平跳变(一个完整高低周期),对应晶振的一次振荡。

这个信号,就是后面讲的时钟周期的来源。


四、三大周期详解:时钟周期 → 机器周期 → 指令周期

这是嵌入式开发最容易混淆的一组概念,它们是逐级包含的关系:

指令周期(Instruction Cycle)
└── 包含若干个机器周期(Machine Cycle)
    └── 包含若干个时钟周期(Clock Cycle / Oscillation Cycle)

4.1 时钟周期(振荡周期,Tcy)

晶振频率时钟周期
12MHz1/12 μs ≈ 83.33ns
11.0592MHz≈ 90.42ns
6MHz1/6 μs ≈ 166.67ns

4.2 机器周期(Machine Cycle,Mc)

传统12T的51单片机:内部固定12分频。 晶振输出12MHz原始时钟 → 经过内部12分频 → 每12个时钟脉冲产生1个机器周期脉冲

以12MHz晶振、传统12T 51为例:
时钟周期 = 1/12 μs
机器周期 = 12 × 时钟周期 = 1 μs

STC新款1T单片机,可以配置分频系数为1:不做分频,时钟直接等于机器周期,执行速度大幅提升。

常见MCU分频系数对比

MCU系列分频系数12MHz下机器周期
传统8051(12T)121 μs
增强型51(6T)60.5 μs
STC 1T系列1(可配)~83ns
STM32(Cortex-M)通常1(PLL后)取决于主频

4.3 指令周期(Instruction Cycle)

51单片机指令周期分类(以12T 12MHz为例):

指令类型机器周期数实际耗时典型指令
单周期指令11 μsMOV A, RnNOPINC A
双周期指令22 μsMOV direct, directSJMP
四周期指令44 μsMUL AB(乘法)、DIV AB(除法)

所以在51单片机中,虽然晶振频率是12MHz,但执行最快的单周期指令也只能做到1μs一条,平均指令执行速度大约是 0.5~1 MIPS(百万指令每秒)。

4.4 完整时间关系图(12MHz 12T 51)

时间轴(μs):  0      1/12   2/12  ...  11/12    1      2      ...
               ├──────┼──────┼──────┼──────┼──────┼──────┼──────┤
时钟周期:       | T1 |  T2 |  T3 | ... | T12|
               └──────── 1个机器周期(1μs) ────────┘
               └──── 单周期指令(如NOP) ────┘
               └──────── 双周期指令(如SJMP) ─────────┘

五、时钟信号全链路完整流程串一遍

把前面的所有环节串联起来,从物理振动到CPU执行指令:

  1. 上电:单片机内部放大器通电,XTAL1和XTAL2引脚激活。
  2. 起振:XTAL1/XTAL2外接石英晶体+负载电容,正反馈环路建立。
  3. 压电振动:石英晶体利用压电效应,以固定频率机械振动,输出正弦电信号。
  4. 施密特整形:内部施密特电路把正弦波整形为数字方波,得到原始时钟(对应时钟周期)。
  5. 分频器:内部分频器对原始时钟做分频(传统51是12分频),得到机器周期节拍。
  6. CPU取指执行:CPU按照机器周期节拍,取指令、译码、执行——一条指令可能占1~4个机器周期,这就是指令周期
  7. 外设同步:定时器、串口、GPIO等全部外设同步跟随这个节拍,每一个节拍执行内部硬件动作。

CPU所有操作,全部跟着这个时钟脉冲走。没有时钟,CPU就不会工作,程序停止运行——这也是为什么晶振电路是MCU最核心、最不能出错的电路之一。


六、RC振荡电路原理

晶振不是唯一的时钟来源。很多MCU内部都集成了RC振荡器,可以不用外部晶振就直接运行。理解RC振荡的原理,才能真正明白晶振和RC各自的优劣。

6.1 RC电路的充放电基础

RC电路由一个电阻(R)和一个电容(C)串联组成,核心特性是电容的指数充放电:

充电过程(通过电阻R给电容C充电):

    Vcc ──[ R ]──┬── C ── GND

             Vout (电容两端电压)

充电时: Vout(t) = Vcc × (1 - e^(-t/RC))
放电时: Vout(t) = V0 × e^(-t/RC)

其中 τ = RC时间常数,单位是秒。它决定了充放电的快慢:

举例:R=10kΩ,C=100pF → τ = 10k × 100p = 1μs → 充放电时间在微秒级。

6.2 如何用RC产生振荡

光有RC充放电是不够的,必须加上比较器/施密特触发器+开关构成反馈环路,才能持续振荡:

典型RC张弛振荡器结构:

          ┌───────────────┐
          │ 施密特触发器  │
  Vout ──►│              ├──► GND(放电开关)
          │   Vth_up     │
          │   Vth_down   ├──► Vcc(充电开关)
          └───────┬───────┘

        输出方波 ◄─┘

        [ R ] ◄───┘(充放电路径)

              C ──┴── GND

工作循环:

  1. 阶段A(充电):开关接到Vcc,通过R给C充电。电容电压上升 → 升到上限阈值 Vth_up → 触发器翻转。
  2. 阶段B(放电):开关接到GND,C通过R放电。电容电压下降 → 降到下限阈值 Vth_down → 触发器再次翻转。
  3. 回到阶段A,如此循环往复,输出连续方波。

振荡频率估算

f ≈ 1 / (2.2 × R × C)    (系数取决于阈值比例,典型约0.7/0.3分位)

6.3 RC振荡器的特点

特性RC振荡器石英晶振
精度差(±5%~±20%甚至更大)极高(±20ppm~±100ppm,即百万分之几十)
温漂大(温度变化R和C都会变)极小
成本极低(片内无需额外元件)需要外部晶体+电容
起振稍慢(ms级起振时间)
功耗相对高
适用场景对时序不敏感(简单GPIO、LED闪烁)串口通信、定时器、高速CPU

ppm是什么? ppm = parts per million,百万分之一。 11.0592MHz晶振 ±30ppm → 频率误差 = 11.0592M × 30/1,000,000 ≈ ±332Hz,极小。 而内部RC振荡器 ±10% → 误差可达 ±1.1MHz,差3个数量级!

6.4 为什么串口一定要用晶振?

串口(UART)通信的核心是双方波特率必须一致,否则采样点错位就会出错。

波特率误差影响分析(以9600bps为例):
- 每一位持续时间 = 1/9600 ≈ 104.17 μs
- 1位起始 + 8位数据 + 1位停止 = 10位/字节
- 采样点通常在每位的中间位置

若晶振误差 ±20ppm:10位累计误差 ≈ 0.0002% → 完全没问题
若RC误差 ±5%:   第10位采样点可能偏移近半个位宽 → 错误率飙升

这就是为什么做串口一定要用晶振,而且常用11.0592MHz这个”奇怪”的频率—— 因为11.0592MHz经过分频后可以得到整数波特率(9600、19200、115200等),完全没有分频小数误差。 如果用12MHz晶振算标准波特率,会产生约 0.16%~8.5% 的固有误差,高波特率下会丢包。

6.5 延伸:11.0592MHz 这个”奇怪”的频率是怎么算出来的?

很多初学者第一次看到 11.0592MHz 都会纳闷:为什么不取个整数,比如 11MHz 或 12MHz?其实这个数字是精确设计出来的,不是巧合。下面一步步推导给你看。

第一步:51串口波特率的计算公式

传统51单片机的串口(UART)通常用定时器2或**定时器1的模式2(8位自动重装)**产生波特率时钟。以最常用的定时器1模式2为例,波特率公式如下:

波特率 = (2^SMOD / 32) × (定时器溢出率)

其中:
- SMOD:PCON寄存器的第7位,波特率加倍位(0或1)
- 定时器溢出率 = 晶振频率 / (12 × (256 - TH1))
         ↑因为51是12T,定时器每个机器周期+1
         TH1是定时器1高8位的重装值(整数,范围0~255)

把溢出率代入波特率公式,合并后:

波特率 = (2^SMOD × Fosc) / (32 × 12 × (256 - TH1))
       = (2^SMOD × Fosc) / (384 × (256 - TH1))

关键观察:TH1 必须是整数(0~255),所以 (256 - TH1) 也必须是整数(1~256)。 👉 这意味着:如果要让波特率精确等于标准值,等号右边的所有因子必须能整除,不能出现小数——否则TH1取任何整数都凑不出精确的波特率,必然存在误差。

第二步:从标准波特率反推 Fosc 需要满足什么条件

常用的标准波特率是一套约定俗成的数列:

常用波特率
12001200 bps
24002400 bps
48004800 bps
96009600 bps
1920019200 bps
3840038400 bps
5760057600 bps
115200115200 bps

这些数字不是随便取的,它们之间都是 2倍关系(1200→2400→4800→9600→115200)。 最小公约数可以追溯到 1200×96 = 115200,最大的那项刚好是 115200。

现在把公式变形,反解 Fosc:

Fosc = (波特率 × 384 × (256 - TH1)) / 2^SMOD

假设我们想要9600波特率,并取 SMOD=0(不加倍),(256-TH1)=3(一个合理的整数值):

Fosc = 9600 × 384 × 3 / 1 = 11,059,200 Hz = 11.0592 MHz
                 ↑ ↑
          这就是为什么是11.0592!

看到了吗?11,059,200 就是精确算出来的整数,不是拍脑袋取的。

第三步:验证 11.0592MHz 下所有常用波特率是否都是整数

用 Fosc = 11.0592MHz 代回公式,计算各波特率需要的 TH1:

公式:(256 - TH1) = (2^SMOD × 11059200) / (384 × 波特率)
波特率SMOD计算 (256-TH1)TH1重装值说明
1200024FD (253)✅ 整数
2400012F4 (244)✅ 整数
480006FA (250)✅ 整数
960003FD (253)整数,最常用组合
1920001.5 → 加倍SMOD=1 → 3FD (253)✅ 整数
5760011FF (255)✅ 整数
11520010.5 → 用定时器2才能实现✅ 定时器2模式下整数

表格里全部都是整数 → 意味着波特率没有任何误差,这就是11.0592MHz的魔力!

第四步:对比 12MHz 晶振会产生多少误差

同样用公式,把 Fosc = 12MHz 代进去算:

以9600波特率、SMOD=1为例:
(256 - TH1) = (2 × 12000000) / (384 × 9600)
           = 24000000 / 3686400
           ≈ 6.5104...  ← 不是整数!

TH1只能取整数,所以在6和7之间二选一:

TH1取法实际波特率理论波特率误差率
取 (256-7)=249 → TH1=F99216 bps9600 bps-4.0%
取 (256-6)=250 → TH1=FA10714 bps9600 bps+11.6%

9600波特率下12MHz的误差居然超过 ±4%!而UART通信一般要求两边波特率误差总和不能超过±2%~±3%,否则就会丢包乱码。这就是为什么12MHz虽然是整数频率,做串口反而不如一个”奇怪”的11.0592MHz好用。

再看 11.0592MHz 下同样9600的对比:

晶振TH1计算值实际TH1误差率
11.0592MHz3.0(精确整数)30.000%
12MHz6.5104(非整数)凑不出来-4.0% ~ +11.6%

第五步:11.0592 这个数还能怎么看?

其实这个数可以用多种方式拆解,每一种都印证了它的设计目的:

11,059,200 = 9600   × 1,152      ← 9600波特率 × 1152(公式中的系数因子)
            = 19200  × 576
            = 115200 × 96        ← 115200波特率 × 96
            = 1,843,200 × 6      ← 1.8432MHz(另一种常用晶振)× 6
            = 384 × 28800        ← 公式中384系数 × 28800

1.8432MHz 也是一个常见晶振频率,常用于低速串口芯片(如 MAX232 周边),它和 11.0592MHz 是6倍关系——道理是一样的,都是为了让波特率计算出来是整数。

总结

11.0592MHz 不是什么神秘数字,而是由51单片机的定时器结构+标准波特率数列共同约束出来的唯一精确整数解

三个条件联立 → 唯一能同时满足所有常用波特率都算出整数TH1的频率,就是 11,059,200 Hz = 11.0592 MHz。 这就是为什么你在几乎所有涉及串口通信的51单片机电路板上,都能看到这颗晶振的身影。


七、常见实际问题(做硬件会遇到)

7.1 晶振不起振

7.2 晶振频率不准

7.3 内部RC导致串口乱码

7.4 电磁干扰(EMI)


八、晶振 vs RC振荡器对比总结

维度石英晶振(Crystal)RC振荡器
物理原理石英晶体压电效应,机械共振电阻电容充放电 + 施密特触发
精度极高(ppm级)低(百分比级)
温漂极小
外部元件需晶振+2个负载电容无需(片内RC可省掉全部外部件)
成本略高极低
频率稳定度非常好
典型应用MCU主时钟、串口、USB、以太网看门狗、低功耗唤醒、简易LED/按键

选择原则:

  • 只要涉及通信(UART/SPI/I2C/USB)、定时精度要求 → 必须用晶振
  • 纯GPIO操作、LED闪烁、按键扫描 → 可以用内部RC省钱

九、回顾:概念串联图

石英晶体(物理)
    │ 压电效应 + 逆压电效应

机械振动(固有频率,只与尺寸有关)
    │ 配合MCU内部放大器 + 正反馈 + 负载电容

正弦波振荡信号
    │ 施密特触发器整形

数字方波 ────────► 时钟周期(Tcy = 1/f晶振)───┐
                                                │ 分频器(51=12分频,STM32=PLL)

                                         机器周期(Mc = N × Tcy)
                                                │ CPU执行微操作

                                         指令周期(1~4个Mc,取决于指令)


                                         程序一条一条跑起来!

总结

一句话串起全文:

晶振本身只是一块压电石英薄片,靠单片机内部放大电路构成正反馈回路,把晶体固定频率的机械振动转化为稳定的数字时钟节拍;时钟经过分频得到机器周期,CPU按照机器周期的节拍一步步取指执行,每条指令占用1到多个机器周期——这就是指令周期。

而RC振荡器虽然成本低、无需外部元件,但因为充放电的物理特性决定了它精度差、温漂大,只能用于对时序不敏感的场景;一旦涉及通信或精确计时,晶振是不可替代的选择。


分享这篇文章到:

下一篇文章
问题处理的三种方式:从"救火"到"无事发生"