转自:《编码的奥秘》 第十四章
人人都知道电可以使物体运动。随便看一眼就会发现,很多家用电器中都装了电动机,如钟、风扇,食品加工机、 C D机等等。电也能使扬声器中的磁芯振动,从而使音响设备、电视机产生了声音、话音和音乐。不过,电使物体运动的一个最简单、最神奇的例子可能是电子蜂鸣器和电铃。
将继电器、电池、开关按如下形式连接:
如果你觉得它看起来很奇怪,则你还没有发挥出你的想像力。我们还从未见过如此连接的继电器。原来的继电器中,输入和输出通常是分开的,这里却构成一个闭环。当闭合开关时,电路连通了:
接通的电路使电磁铁把金属簧片拉下来(电流的作用):
当金属簧片改变位置后,电路不再完整,电磁铁失去了磁性,金属簧片又弹回原来的位置:
这样,电路便又一次接通了。可见,只要开关是闭合的,金属簧片就会上下跳动—使电路闭合或断开— 并制造一种声音。如果金属簧片制造了一种刺耳的声音,它就构成了一个蜂鸣器。如果金属簧片附上一把小锤子,再加一个金属锣,它就构成了一个电铃。
有两种方法可用来连接继电器以构造一个蜂鸣器,下面是另一种方法的描述:
你可能从上述图中认出了这是第 11章介绍过的反向器,所以电路可以简化为:
对于反向器而言,当输入为 0时,输出为 1 ;输入为 1 时,输出为 0。在该电路中闭合开关会使反向器中的继电器间断地闭合和断开。如果去掉开关,可以使反向器连续地工作,如下图示:
这幅图似乎在演示一种逻辑矛盾,反向器的输出是和其输入相反的,但是在这里,其输出同时又是其输入。需要特别指出的是,反向器实际上是一个继电器,而继电器从一个状态转换到另一个状态是需要时间的。所以,即使输入和输出是相等的,输出也会很快地改变,成为输入的倒置(当然,随即输出也就改变了输入,如此反复)。
电路的输出是什么呢?其实就是提供电压和不提供电压之间的变换。或者说输出要么是 0,要么是 1 。
这个电路称为振荡器 ,它和我们以前见到的每样东西都有本质上的区别。以前,所有的电路都靠手动地断开或闭合开关来改变状态,而振荡器却不需要人的干涉,它可以自主地工作。
当然,单独的一个振荡器不会有什么用,但在本章的后面及接下去的几章里,你会看到这个电路和其他电路连接后构成了自动控制中一个十分关键的部分。所有计算机都靠某种振荡器来使其他部件同步工作。
振荡器的输出是 0和1 的交替序列,可以用下图形象地来表示它:
图中,水平轴表示时间,垂直轴表示输出是 0或1 :
此图表示随着时间的变化,振荡器的输出在 0和 1 之间交替变化。基于这个原因,振荡器有时称为 时钟 ( c l o c k),因为通过对振荡次数记数还可确定时间。
那么,振荡器运行的速度有多快呢?也就是说,金属簧片上下跳动的频率是多少?每秒有多少次呢?很明显,这依赖于继电器是如何构造的。容易想到,一个大的、笨重的继电器只能迟钝地上下摆动;而一个小的、轻巧的继电器可以迅速地跳动。】
我们把振荡器从某个时间的输出开始,经历一段变化又回到同样输出的这一段间隔称为振荡器的一个循环( c y c l e):
一个循环所需要的时间称为振荡器的周期。假设一个振荡器的周期是 0 . 0 5秒,则可以在水平轴上标出时间:
振荡器的频率是周期的倒数。本例中,若振荡器的周期是 0 . 0 5秒,则其频率是 1 ÷ 0 . 0 5秒,即每秒钟 2 0个循环。这表明振荡器的输出每秒钟改变 2 0次。
每秒循环数与每小时英里数、每平方英寸磅数、每份食物(饮料)的卡路里数等毋需多解释的术语一样是一个很容易理解的概念,但已不常用。为了纪念第一个发送和接收无线电波的人—鲁道夫·赫兹 ( 1 8 5 7- 1 8 9 4 ),我们用“赫兹”这个词表示每秒的循环数。这个用法始于2 0世纪2 0年代的德国,后来传到其他国家。
于是,我们可以说这个振荡器的频率是 2 0赫兹,或直接简写为 2 0 H z。
到目前为止,我们只是在假设一个振荡器的速度。到本章末尾,我们可以构造一种器件来真正地测量一个振荡器的速度。
为了构造这个器件,先看一个用特殊方式连接的一对或非门。或非门的特点是只有两个输入都为 0时,输出才为 1 :
下图是含有两个或非门、两个开关和一个灯泡的电路:
注意图中奇特的连接方式:左边或非门的输出是右边或非门的输入,右边或非门的输出是左边或非门的输入。这是一种反馈。事实上,这和在振荡器中类似,输出又返回作为一种输入。这是本章中大部分电路的特点。
在上图电路中,一开始,只有左边或非门的输出有电流,因为它的两个输入均为 0。现在闭合上面的开关,左边或非门的输出变为 0,于是右边或非门的输出变为 1 ,灯泡点亮:
神奇之处在于当你断开上面的开关时,由于或非门的输入中只要有一个为 1 ,其输出就是0,因而左边或非门的输出不变,灯泡仍然亮着:
你不觉得奇怪吗?两个开关都断开着,和第一幅图一样,但灯泡却亮着。这种情形和以前所见到的完全不同。通常,一个电路的输出仅仅依赖于输入,这里的情况却不一样。无论断开或闭合上面的开关,灯泡总是亮着。这里开关对电路没有什么影响,原因是左边或非门的输出一直是 0。
现在闭合下面的开关。由于右边或非门的输入中有一个是 1 ,则其输出变为 0,灯泡熄灭。左边或非门的输出此刻变为 1 :
现在,再断开下面的开关,灯泡仍旧不亮:
此电路和初始电路一样。然而这回却是下面开关的状态对灯泡没有什么影响。总结起来就是:
• 闭合上面的开关使灯泡点亮,当再断开时,灯泡仍然亮着。
• 闭合下面的开关使灯泡熄灭,当再断开时,灯泡仍然不亮。
电路的奇特之处是:有时当两个开关都断开时,灯泡亮着;而有时,当两个开关都断开时,灯泡却不亮。当两个开关都断开时,电路有两个稳定状态,这样的一个电路称为触发器。触发器是 1 9 1 8年在英国射电物理学家 William Henry Eccles(1875 -1 9 6 6 )和 F. W. J o r d a n的工作中发明的。
触发器电路可以保持信息,换句话说,它有记忆性。它可以“记住”最近一次是哪个开关先闭合的。如果你遇到这样一个触发器,它的灯泡亮着时,你可以确定最近闭合的是上面的开关;而灯泡灭着时则是下面的开关。
触发器和跷跷板很像。跷跷板有两个稳定状态,它不会长期停留在不稳定的中间位置。你只要一看跷跷板就知道哪边是最近被压下来的。
触发器是十分关键的工具,尽管你现在可能还没看出来。它们赋予电路“记忆”,使其知道以前曾有过的状态。想像一下,如果你没有记忆力,你该如何去数数,你记不住你刚数过的数,当然也无法确定下一个数是什么。同样,一个能计数的电路(本章后面要提到)必定需要触发器。
触发器有很多种,刚才所看到的是最简单的一种,称为 R - S(或 R e s e t - S e t,复位 /置位)触发器。下面以对称的方式把它重新绘出来:
用于点亮灯泡的输出称为 Q,另一个输出 -Q是Q的倒置。如果 Q是0, -Q就是 1 ,反之亦然。两个输入端 S( S e t)和 R( R e s e t)分别表示 置位和复位。你可以把“置位”理解为把 Q设为1 ,而“复位”是把 Q设为0。当 S为1 时(对应于前面图中闭合上面开关的情况), Q变为1 而Q- 变为0;当 R为1 时(对应于前面图中闭合下面开关的情况) , Q变为 0而-Q变为 1 。当 S和 R都为 0时,输出保持 Q原来的状态。输入与输出的关系小结于下表中:
这张表称为功能表 、 逻辑表 或真值表 。它指明不同的输入组合能产生不同的输出结果。由于R - S触发器有两个输入端,因而不同的输入组合有 4种,分别对应于表中的 4行。
注意表中倒数第 2行中 S和 R均为零,而输出标识为 Q和 -Q。这表示当 S和 R输入均为零时,Q和 -Q端的输出保持 S、 R同时设为 0以前的输出值。表中最后一行说明 S 和R输入都为 1 是非法的、禁止的。这是因为 S、 R同时为 1 时,两个输出 Q和-Q均为零,这与 Q和Q- 互为倒置的关系相矛盾。所以,当你用 R - S触发器设计电路时,要避免使 R、 S输入同时为 1 的情况。
R - S触发器通常画成有两个输入,两个输出的方块图,如下图所示:
R - S触发器能够记住哪一个输入端最近被输入高电位,这确实很有趣。但更有用的电路应该能记住某个特定时间点上上一个信号是 0还是1 。
在实际构造这种电路之前,先来思考一下它的行为功能。它需要两个输入,其中一个称为数据端 ( D a t a)。像所有数字信号一样,数据端输入可以是 0或1 。另一个输入称为 保持位( Hold that bit)。通常情况下,保持位设为 0,这时,数据端对电路没什么影响。当保持位置为1 时,电路就反映出数据端的值。接着,保持位又置为 0,这时,电路将记住数据端输入的最近一个值。数据端信号的任何改变不会对电路再有影响。
换句话说,它的功能表可以这样写:
在前两种情况下,保持位置为 1 , Q端输出和数据端输入相同;后两种情况下,当保持位置为 0时, Q端输出和它以前的值相同,即保持原状态。注意,后两种情况中当保持位为 0时,Q端输出不再受数据端输入的影响,功能表可以简化表示为:
X表示不关心其取值情况,它的值对于电路输出没有影响。
基于R-S 触发器来实现保持位的功能要求在输入端增加两个与门,如下图所示:
要使与门输出为 1 ,两个输入端必须同时为 1 。在上图中, Q输出为0,而-Q输出为 1 。
只要保持位置为 0,置位信号对于输出就没有影响:
同样,复位信号对电路输出也没有影响:
只有当保持位信号是 1 时,电路的功能才和前述的 R - S触发器相同:
这时,由于上面与门的输出和复位端输入相同,而下面与门的输出和置位端输入相同,所以此电路的功能就和普通的 R - S触发器是一样的了。
但我们还没有达到目标,我们只想要两个输入,而不是三个,怎么办呢?前面讲过 R - S触发器中两个输入同时为 1 的情况是禁止的;而两个输入同时为零的情况没有什么意义,因为那只是输出保持不变的简单情况。这里,只要将保持位置为 0,就可以完成同样的功能。
可见,真正有意义的输入是 S为0, R为1 或R为0, S为1 。把数据端信号当作置位信号,它取反后的值就是复位端信号,如下图示:
在这种情况下, S和 R输入以及输出 Q均为 0, Q- 为1 。只要保持位为 0,数据端输入对于电路输出就没有影响:
当保持位为 1 时,电路反映出数据端输入的值:
Q端输出现在和数据端输入是一致的, Q- 则相反。现在,保持位又回到 0:
这时,电路会记得当保持位最后一次置为 1 时数据端输入的值。数据端以后的变化对电路的输出没有影响
这个电路称为电平触发的 D型触发器 , D( D a t a)表示数据端输入。所谓 电平触发 是指当保持位输入为某一特定电平(本例中为“ 1 ”)时,触发器才对数据端的输入值进行保存。 (很快,你将会看到另一种形式的触发器。 )
通常情况下,当这样一个电路出现在书中时,输入并不被标为保持位,而是标为“时钟”。当然,这个信号并不是一个真的时钟,但它有时却具有类似钟一样的属性,即在 0和 1 之是有规律地来回变化。但是现在时钟只是用来指示什么时候保存数据:
把数据端简写为 D,时钟端简写为 C l k,其功能表如下所示:
这个电路就是所谓的电平触发的 D型锁存器 ,它表示电路锁存住一位数据并保持至将来使用。它也可以称为 1 位存储器 。本书将在第 1 6章中说明如何将多个 1 位存储器连起来以构成多位存储器。
在锁存器中保存多位值是很有用的。假如你想用第 1 2章中的加法机把三个 8位数加起来,你可以在第 1 行开关上输入第一个加数,在第 2行开关上输入第二个加数,但是你必须把第一次加法运算的结果记录下来,然后以同样方式把记下来的结果和第三个加数再用开关输入。这是十分麻烦的。
使用锁存器可以解决这个问题。让我们把 8个锁存器集成到一个盒子里,形成一个 8位锁存器 。每个锁存器用到两个或非门、两个与门和 1 个反向器。时钟端输入是互相连在一起的。结果如下图所示:
这个锁存器一次可以保存 8位数。上面的 8个输入标为 D0~D7,下面的 8个输出标为 Q 0~Q 7。左边的输入是时钟( C l k),时钟信号通常为 0。当时钟信号为 1 时, D端输入被送到 Q端输出。当时钟信号变为 0时, 8位输出值保持不变,直到时钟信号再次被置为 1 。 8位锁存器也可以画成下面的样子:
下面是 8位加法器 :
通常(先不考虑上一章的减法), 8个A输入和 8个B输入是连在开关上的, C I(进位输入)端接地, 8个S(和输出)和 C O(进位输出)端连着灯泡。
经修改, 8位加法器的输出既与灯泡相连,也作为 8位锁存器的数据端 ( D )输入。标为“保存”( S a v e)的开关是锁存器的时钟输入,用于保存加法器的运算结果:
标识为 2 - 1 选择器的方块是让你用一个开关来选择加法器的 B端输入是取自第 2排开关还是取自锁存器的 Q端输出。当选择开关闭合时,就选择了用 8位锁存器的输出作为 B端输入。 2 - 1选择器用了 8个如下电路:
如果选择( S e l e c t)端输入为 1 ,或门的输出和 B端输入是一样的。这是因为上面与门的输出和 B端输入是一样的,而下面与门的输出是 0。同样,如果选择端输入是 0,或门的输出则和A端输入是一样的。总结起来如下表所示:
修改后的加法机中包含了 8个这样的 1 位选择器。所有选择端的信号输入是连在一起的。
改进过的加法机不能很好地处理进位输出 ( C O )信号。如果两个数的相加使进位输出信号为1 ,则当下一个数再加进来时,这个信号就被忽略了。一个可能的解决方法是使加法器、锁存器、选择器均为 1 6位宽度,或者至少比你可能遇到的最大的和的位数多一位。这个问题会在第1 7章中专门讲述。
对加法机一个更好的改进方法是完全去掉一排开关,但是这需要先对 D触发器做一点儿小的改进,对它加一个或门和一个称为清零( C l e a r)的输入信号。清零信号通常为 0,但当它为1 时, Q输出为 0,如下图所示:
无论其他信号是什么,清零信号总迫使 Q输出为 0,起到了给触发器清零的作用。
你也许还不明白为什么要设置这个信号,为什么不能通过把数据端输入置 0和时钟端输入置1 来使触发器清零呢?这也许因为我们并不能控制数据端的输入。下图中, 8个锁存器连着 8位加法器的输出:
注意,标识为“相加” ( A d d )的开关此刻控制着锁存器的时钟输入。
你可能会发现这个加法器比前面那个好用,尤其是当你需要加上一长串数字时。刚开始时,按下清零开关,这个操作使锁存器输出为 0,并熄灭了所有的灯泡,同时使加法器的 B端输入全为 0。接着,通过开关输入第一个加数,闭合“相加”开关,则此加数反映在灯泡上。再输入第二个数并再次闭合“相加”开关,由开关输入的 8位操作数加到前面的结果上,其和输出到灯泡。如此反复,可以连加很多数。
触发器是电平触发式的,意思是说只有在时钟端输入从 0变到 1 后(即高电平时),数据端输入的值才能保存在锁存器中。注意,在时钟端输入为 1 期间 ,数据端输入的任何改变都将反应在Q或Q- 端的输出值上。
对一些应用而言,电平触发时钟输入已经足够用了;但对另外一些应用来说, 边沿触发时钟输入更为适用。对于边沿触发器而言,只有当时钟从 0变到 1 的瞬间,输出才会改变。在电平触发器中,当时钟输入为 0时,数据端输入的任何改变都不会影响输出;而在边沿触发器中,当时钟输入为 1 时,数据端输入的改变也不会影响输出。只有在时钟输入从 0变到1 的瞬间,数据端的输入才会影响边沿触发器的输出。
边沿触发的 D型触发器是由两级 R - S触发器按如下方式连接而成的:
这时,时钟输入既控制着第一级,也控制着第二级。但是应该注意到时钟信号在第一级中取了反,这意味着除了当时钟信号为零时保存数据外,第一级工作原理和 D型触发器完全相同。第二级的输出是第一级的输入,当时钟信号为 1 时,它们被保存。总的结论就是只有当时钟信号从0变为1 时,数据端输入才会保存下来。
让我们进一步分析。下面是处于非工作状态的触发器,其数据端、时钟输入均为 0, Q端输出也是 0:
现在,使数据端输入为 1 :
这改变了第一级触发器状态,因为时钟信号取反后为 1 。但第二级仍保持不变,因为时钟端输入仍为 0。现在把时钟输入变为 1 :
这就引起第二级触发器改变,使 Q端输出变为 1 。与前面不同的是现在无论数据端输入如何变化(如变为 0),它也不会影响 Q端的输出值:
Q和Q- 端输出只有在时钟输入从 0变到1 的瞬间才发生改变。
边沿触发的 D型触发器的功能表需要一个新符号来表示这种从 0到1 的瞬时变化,即用一个向上指的箭头(↑)表示:
箭头表示当 C l k信号从 0变到1 时, Q端输出和数据端输入是一样的,这称为 C l k信号的“正跳变”(“负跳变”是从 1 到0的转换) 。触发器的符号图如下所示:
图中的小三角符号表示触发器是边沿触发的。
现在向你展示一个使用边沿触发器的电路。先回忆一下本章开始构造的振荡器,振荡器的输出是在 0和1 之间变化的:
把振荡器的输出连到边沿触发的 D型触发器的时钟输入端,并把 端输出连到自己的 D输入端:
触发器的输出同时又是它自己的输入。 (实际上,这种构造可能是有问题的。振荡器是由来回迅速转变状态的继电器构成的。振荡器的输出和构成触发器的继电器相连,而这些继电器不一定能跟上振荡器的速度。为了避免这些问题,这里假设振荡器中继电器的速度比这个电路中其他地方的继电器的速度都慢。 )
观察下面的功能表,就可以明白电路中发生的情况了。刚开始时, C l k输入和 Q端输出都是0,则 Q 端输出为 1 ,而它和 D输入是相连的:
当C l k信号变回为 0时,不会影响输出:
现在C l k信号再变为 1 。由于 D输入为 0,则 Q为0且-Q为1 :
所以 D输入也变为 1 :
以上发生的情况总结起来就是:每当 C l k输入从0变到1 时, Q端输出就发生改变,或者从 0变到1 ,或者从 1 变到0。看看下面的图,问题就更清楚了:
当C l k输入从 0变到 1 时, D的值(与 的值是相同的)被输出到 Q端。当下一次 C l k信号从0变到1 时,同样会改变 D和 的值。
若振荡器的频率是 2 0赫兹(即每秒 2 0次循环) ,则 Q的输出频率是它的一半,即 1 0赫兹。由于这个原因,这种电路 (其中 输出依循触发器的数据端输入 )称为分频器。
当然分频器的输出可以是另一个分频器的 C l k输入,并再一次进行分频。下面是三个分频器连在一起的情况:
让我们来看一下上图顶部的 4个信号的变化规律:
这里只给出了这幅图的一部分,因为这个电路会周而复始地变化下去。从这个图中,有没有发现使你眼熟的东西?
提示你一下,把这些信号标上 0和1 :
现在看出来了吗?把这个图顺时针旋转 9 0度,读一读横向的 4位数字,每一组输出都对应了十进制中 0~1 5中的一个数:
这个电路只具备了一个计数功能,如果再多加上几个触发器,它就可能计更多的数。第 8章曾指出在一个递增的二进制数序列中,每一列数字在 0和 1 之间变化的频率是其右边那一列数字变化频率的一半,这个计数器模仿了这一点。时钟信号每一次正跳变时,计数器的输出就递加了 1 。
可以把8个触发器集成于一个盒子里,构成一个 8位计数器:
这个计数器称为 8位行波(异步)计数器,因为每一个触发器的输出都成为下一个触发器的时钟输入。变化是沿着触发器一级一级地传递的,最后一级触发器的变化必定要延迟一些。更复杂的计数器是“并行(同步)计数器”,在这种计数器中,所有输出是同时改变的。
输出端信号已标识为从 Q0~ Q7, Q0是第一个触发器的输出。如果把灯泡连到这些输出上,就可以把 8位结果读出来。
这样一个计数器的时序图可以把 8个输出分开来表示,也可以把它们一起表示,如下图所示:
时钟信号的每个正跳变发生时,一些 Q输出可能改变,另一些可能不改变,但总体上是使原来的结果递增了 1 。
本章前面曾提到过可以找到某种方法来确定振荡器的频率,现在这个方法已经找到了。如果把振荡器连到 8位计数器的时钟输入上,计数器会显示出振荡器经历了多少次循环。当计数器总和达到 11111111 时,它又会返回到 0 0 0 0 0 0 0 0。使用计数器确定振荡器频率的最简单方法是把计数器的输出连到 8个灯泡上。当所有输出为 0时(即没有一个灯泡点亮),启动一个秒表;当所有灯泡都点亮时,停住秒表。这就是振荡器循环 2 5 6次所需要的时间。假设是 1 0秒钟,则振荡器的频率就是 2 5 6÷ 1 0,或者说是 2 5 . 6赫兹。
当触发器功能增加时,它也变得更复杂。下面这个触发器称为具有预置( P r e s e t)和清零功能的 边沿触发的 D型触发器
通常情况下,预置和清零信号输入会忽视时钟和数据端输入,且均为 0。当预置信号输入为1 时, Q变为 1 , 变为0。当清零信号为 1 时, Q为0, 变为1 (同 R - S触发器中的 S和R输入一样,预置和清零信号不能同时为 1 )。其他情况下,该触发器的行为和普通边沿触发的 D型触发器是一样的。
电路图符号可以简化地用下图代替:
现在,我们已经知道如何用继电器来做加法、减法和计数,是不是很有成就感?因为我们所用的硬件是 1 0 0多年以前就存在的东西,我们还有更多的空间去探索。但是先暂时休息一下,不用再去构造什么,回过头来再看看关于数字的问题吧。
(ps:看完的感受是,全程懵逼~)