A6 存储基础
现在你已经能让电路计算 8 位加法了。但有个尴尬的问题:每次机器算完,难道还要你手抄到纸上记住吗?这也太不智能了。
而你那位久违的发小发现,他经常玩的跷跷板或许可以解决这个问题。跷跷板总是一头向下、另一头向上,很少两边平衡——这意味着,只要看一眼哪边高哪边低,就知道当前的状态。要是电路也能停在"两种姿势"中的某一种,那它不就记住上一个信号了吗?
把输出接回输入 = 记忆。
这个跷跷板电路要怎么搭?答案的主角是或非门(NOR)。先把它的真值表摆出来——两个输入都是 0 时输出 1,其余情况全部输出 0:
| A | B | A NOR B |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 0 |
会自己记住的电路
拿两个或非门,把各自的输出交叉接回对方的输入,再配上两个开关、两个灯泡:
两个 NOR 门交叉耦合。初始状态 Q 就是亮的——试试:闭合 Set 灯亮、断开仍亮;闭合 Reset 灯灭、断开仍灭
奇怪的事来了:两个开关都断开,灯泡 Q 却亮着。为什么?因为上方或非门的输出,绕了一圈变成了下方或非门的输入——这根"绕回来的线"叫反馈回路(Feedback Loop)。两个门互相撑住对方,谁也翻不了身,电路就停在了某个状态里。
动手玩几下,规律就出来了:
- 闭合下方 Set 开关 → 灯 Q 亮起;再断开,Q 依然亮着——电路记住了"曾被置位"。
- 闭合上方 Reset 开关 → 灯 Q 熄灭;再断开,Q 依然灭着——电路记住了"曾被复位"。
由于你的发小很喜欢穿人字拖(flip-flops),你俩干脆把这个"会保持姿势的电路"称为 Flip-Flop(触发器)。只要看灯亮还是灭,就知道最后哪个开关被按过——它记住了历史。而上面这个最基础的版本,就是 RS 触发器。
RS 触发器:置位与复位
S 是 Set(置位):把 Q 设成 1;R 是 Reset(复位):把 Q 清成 0;两个都不动(S=R=0)时,Q 保持原样——这就是"记忆"那一行:
| S | R | Q | Q̄ | 含义 |
|---|---|---|---|---|
| 0 | 0 | Q | Q̄ | 保持(记忆!) |
| 1 | 0 | 1 | 0 | 置位 |
| 0 | 1 | 0 | 1 | 复位 |
| 1 | 1 | 0 | 0 | ⚠ 禁止 |
太灵敏了,得加个阀门
RS 触发器能记,但有个毛病:过于灵敏。S 和 R 一动,Q 立刻跟着变。可你真正想要的是——"只在某个特定时刻读入输入,其他时候不管输入怎么变,Q 都不动"。
也就是说,S/R 前面需要一个阀门。你的发小打了一晚上草稿,结论朴素得让人想笑:两个与门就够了。与门本来就是"两个输入都为 1 才放行"——把一个输入接 S(或 R),另一个输入统一接一根新开关,这根开关就叫保持位(Hold That Bit):
带阀门的 RS 触发器。先把 S/R 拨好,保持位 = 0 时怎么拨都没反应;拨到 1 的瞬间,S/R 才被放进触发器
| Hold | S | R | Q | 含义 |
|---|---|---|---|---|
| 0 | × | × | Q | 阀门关死,随便拨 S/R 都不理你 |
| 1 | 0 | 0 | Q | 阀门开着,但 S/R 无动作 |
| 1 | 1 | 0 | 1 | S 放行,置位 |
| 1 | 0 | 1 | 0 | R 放行,复位 |
保持位 = 1,阀门打开,S/R 畅通;保持位 = 0,阀门关死,触发器与世隔绝,安心保持。"什么时候允许改"第一次被一根线控制了。
三个输入太多了:拧成一股
新问题来了:加法器每位只有一个输出,而这个带阀门的触发器有三个输入(S、R、Hold)。S/R 俩输入看着就多余——回看真值表,正常工作时 S 和 R 永远互为相反(除了被禁止的 S=R=1)。那把它们拧成一根线,再加一个反相器自动造出另一路,不就行了?
这根合并后的输入线叫 D(Data)。D=1 时相当于"S=1、R=0",D=0 时相当于"S=0、R=1"——反相器替你保证了两者永远相反,禁止状态从此在物理上绝迹:
D 型锁存器门级电路:S/R 已拧成一根 D + 反相器。拨 D 换值,再拨 Clk 控制阀门开合
保持位也顺手改个名。既然它的职责是"什么时候允许写入",那就叫 Clk(Clock,时钟)吧——现在它还只是一根手动开关,但名字已经预示了它的未来。
谁来按保持位?——时钟
手动拨 Clk 终究是人肉操作。「懒」是第一生产力——与其让人纠结何时按阀门,不如把 Clk 变成一个自动的、有规律的、在 0 和 1 之间来回切换的信号:
0 1 0 1 0 1 0 1 ……
这东西让你想起什么?钟摆。它每摆一个来回,就"嘀嗒"一次,定时打开阀门,告诉触发器:「现在,把输入抓进来存好!」后来大家就把这个按固定节奏跳变的控制信号称作时钟(Clock)——它不是墙上计时的钟表,只是一根按节拍跳 0/1 的控制线。
那这个自动跳变的信号从哪来?还记得 A3 做继电器时的电磁原理吗——通电产生磁性,磁性吸合簧片,簧片反过来又控制电路本身的通断。把继电器的输出绕回它自己的输入:
这个"永远停不下来"的电路就是振荡器(Oscillator)。它的输出波形就是规整的方波:
振荡器输出:0 和 1 交替的方波,每一格是半个周期
周期与频率
振荡器完成一次完整的 0→1→0,就叫一个周期,记作 T;一秒钟完成多少个周期,就叫频率,f = 1/T,单位是赫兹(Hz)。比如 50 Hz,就是每秒跳 50 个来回:
频率 f = 1 / T。频率越高,每秒"嘀嗒"次数越多。
D 型锁存器
把刚才的门级电路装进盒子,只留 Clk、D、Q、Q̄ 四个引脚,就是D 型锁存器(D Latch)。它的行为一句话:电路总会记住"时钟最后一次为 1 期间"的 D 值。因为 RS 已经被拧成了 D,所以这版触发器叫 D 型触发器:
D 型锁存器黑盒。拨 Clk=1,Q 实时跟随 D;拨 Clk=0,Q 锁死,随便改 D 都不理你
| Clk | D | Q | 含义 |
|---|---|---|---|
| 0 | × | Q | 锁存:D 不影响输出 |
| 1 | 0 | 0 | 透明:Q 跟随 D |
| 1 | 1 | 1 | 透明:Q 跟随 D |
现在既然能存 1 位,你和发小熟练地掏出了上一章的祖传手艺——套娃 + 封装。8 个 D 型锁存器并排,8 根 D 输入、8 根 Q 输出,Clk 全部并联,就得到一个能存一个字节的 8 位锁存器:
翻车:会死循环的累加器
拿上一章造好的 8 位加法器,输出接锁存器输入,锁存器输出再绕回加法器的另一路输入——一个累加器就成型了:锁存器初始为 0,拨好一个数,按一下"加"(Clk),和就存进锁存器;再拨下一个数、再按,就完成累加。
第一次按"加",好使,数字存下来了。可你还没松手就发现不对劲:锁存器的输出 Q 变了,它马上传回加法器,加出新的和,新的和又写进锁存器……只要 Clk 还按着(还是 1),这个循环就停不下来,灯泡疯狂闪烁,数字飞速膨胀。
这里涉及一个新概念:电平。Clk=1 的整段时间,电路处于高电平——像一道敞开的门,D 的任何变化都自由穿透到 Q。而你真正需要的,是时钟从 0 跳到 1 的那一瞬间——专业术语叫正边沿 / 上升沿(↑)。就像拍照:快门按下的那一刻定格,之后景里的人怎么动,照片都不变。
只在瞬间拍照:边沿触发
科学不相信眼泪,但可以套娃。把两个 D 型锁存器串起来——第一个叫主级,第二个叫从级,关键的一手是:从级的 Clk 接的是反相后的时钟:
两个门的开关永远错开:主级开门时从级关着,从级开门时主级关着。数据想从 D 走到 Q,必须等两扇门"交接"的那一瞬间——正是上升沿。同样的 Clk 和 D,两种触发方式行为完全不同:
顶栏数字刻度即时刻编号:t2、t6 是时钟上升沿。上:电平触发——t3 处 D 升 1,Q 立刻跟上;t7 处 D 降 0,Q 立刻掉下(Clk=1 期间全程透明)。下:边沿触发——只在 t2、t6 采样:t2 采到 0,Q 不动;t6 采到 1,Q 置 1 并保持;t3、t7 处 D 的变化被完全忽略
为了和电平触发的"锁存器"区分,你在符号的 Clk 引脚里侧加了一个小三角 ▷——这是边沿触发的记号——并称之为边沿触发的 D 型触发器(Edge-triggered D Flip-Flop)。死循环就此终结:Clk 跳完就关门,Q 绕回去也进不来了,累加器老老实实按一下加一次。
分频器:把 Q̄ 接回去
累加器能用了,但没法清零——总不能 24 小时不停累加。用补码加回零当然可以,但得手动输入反码再加 1,太笨。你和发小拿振荡器 + 边沿触发器折腾了一晚上,捣鼓出一个新元件,发小干脆叫它分频器。
它的秘密简单到让人怀疑人生:把 Q̄(非 Q)的输出接回 D 作为输入,时钟端接振荡器:
来逐拍推演一下(这正是上升沿边沿触发的好处——每拍只动一次):
初始 Clk=0、Q=0,于是 Q̄=1;Q̄ 接在 D 上,所以 D=1。
第 1 个上升沿:Q 变成 D 的值 → Q=1;Q̄ 随之变 0,D 跟着变 0。
第 2 个上升沿:Q 又变成 D 的值 → Q=0;Q̄ 变 1,D 跟着变 1。
第 3 个上升沿:你已经看出来了——每来一个上升沿,Q 就翻转一次。 时钟跳 2 次,Q 才跳 1 次——Q 的频率恰好是时钟的一半
如果时钟频率是 20 Hz(每秒循环 20 次),Q 每秒只循环 10 次。频率减半——这就是"分频器"这个名字的由来。
它在数数!——纹波计数器
单个分频器看着只是个"半速开关"。但你顺手把第一个分频器的 Q 接到第二个分频器的时钟端,再依样画葫芦接第三个——第一级每拍翻一次,第二级每两拍翻一次,第三级每四拍翻一次,逐级减半。看着好像也没什么奇怪的,甚至有点无聊。
当发小把每一列的 0 和 1 竖着抄下来的时候,奇迹发生了——它在数数!
竖着读每一列(Q₃Q₂Q₁):000 → 001 → 010 → 011 → 100 → 101……正是二进制数数!
级联分频器天然就是一个二进制计数器:时钟每来一个上升沿,整体 +1。横着看是频率逐级减半,竖着看是数字逐个加一——同一个电路的两种读法,这就是二进制和物理结合的神奇。
老规矩,套娃封装:每个触发器的 Q 作为下一个触发器的时钟,封进一个盒子,就是纹波计数器(Ripple Counter),也叫行波计数器。下面这个是活的,亲手玩玩:
每按一次「脉冲」,Q₀ 翻转;Q₀ 从 1 变 0 时带动 Q₁ 翻转(纹波传导)——和真电路一模一样。数到 255 再加 1 会绕回 0。
清零、预置——还有还愿
计数器有了,但你很快发现一个巨坑:通电瞬间,各触发器的初始值是 0 还是 1 纯看心情——至于谁的心情,不知道。计数器可能从 173 开始数。所以必须有一个一键清零:一根 Clear 线,直接强制所有 Q 归零,不管 Clk 和 D 是什么。对称地,还可以加一根 Preset 线强制 Q 置 1(数字钟"对时"就靠它俩;和 S、R 一样,两根不许同时为 1)。
实现上,电平触发的 D 型触发器加一个或门就能做 Clear;边沿触发的版本复杂些——6 个三输入或非门加一个反相器。但不管内部多复杂,封装起来都是黑盒外面多两个引脚的事。
现在,可以还愿了——还记得周期与频率那节埋的问题吗:振荡器到底跳多快?
顺带一提,石英表里那颗晶振是 32768 Hz——这个数不是选好看的:32768 = 2¹⁵,过 15 级分频恰好得到 1 Hz,每秒一拍。你手腕上的表,走的正是今天这条分频链。
会存 1 位,就会存 8 位;会存 8 位,就敢想 8 万位。
这一章你从"输出接回输入"出发,造出了触发器、锁存器、边沿触发器、分频器和计数器——电路第一次拥有了记忆和节奏。但真正的仓库——能按编号存取成千上万个字节的内存——还差最后一块拼图:地址。下一章,把一个个孤立的锁存器,组织成一座大仓库。
小结 & 思考题(点开深入)
本章你经历了什么
- 输出接回输入 = 记忆:两个 NOR 门交叉耦合 → RS 触发器(S=R=1 禁止)
- RS 太灵敏 → 前面加两个 AND 门当阀门(Hold That Bit)
- S/R 拧成一股 + 反相器 → D 型锁存器,Hold 改名 Clk
- Clk 自动化 → 继电器反馈自激 → 振荡器;f = 1/T(Hz)
- 累加器死循环暴露电平触发的病根 → 主从结构 → 边沿触发(符号 ▷)
- Q̄ 接回 D → 分频器(频率减半);级联 → 纹波计数器(二进制数数)
- 计数器 + 秒表 = 测频率;Clear/Preset 是上电随机的工程补丁
思考题
RS 触发器 S=R=1 时 Q=Q̄=0。如果此时把两个开关同时断开(回到 S=R=0),会发生什么?为什么说结果"纯属抽奖"?
分频器(Q̄ 接 D)初始 Q=0。第 1 个上升沿后 Q=?第 5 个?第 100 个?30 Hz 时钟接 3 级级联,最后一级 Q 的频率是多少?
累加器里,锁存器输出回流到加法器输入。用"门"的比喻说清楚:电平触发为什么停不下来?边沿触发为什么就停得下来?
8 位纹波计数器当前显示 10101010(十进制 170)。再来 3 个时钟脉冲后显示什么?十进制是多少?