通过门电路实现三位 LED 译码器

在前面, 通过继电器及二极管等方式曾实现了一个简易的译码电路, 能够在 LED 数码管上显示 0, 1 和 2.

整合的 LED 数码管, 使用二极管及接地

通过分而治之的方式, 有了另一种实现:

LED 解码采用分解法的一种最终实现

这些实现都极大依赖仔细的分析, 观察, 思考以找到规律并简化, 但最终也仅仅只是能显示三个数字而已.

当然也是可以考虑实现更多数字的显示的, 但恐怕就麻烦不少了.

现在, 运用前述通用的机械公式方式及门电路, 来看看怎么实现它. 而且, 我们打算不止是显示 0, 1, 2, 而是一直显示到 7, 也即总共有 0~7 8 不同个数字.

如此一来, 输出的线路也需要从两根扩展到三根, 三根线正好可以表达 8 种状态.

真值表

第一步依旧是根据 LED 显示 0~7 的要求列出 a~g 对应的二进制数:

LED 数码管显示 0~7 所对应的输入组合

然后, 真值表如下, A, B, C 代表输入(同时也即是加法器的输出, 在译码电路中则作为输入); a, b, c, d, e, f, g 代表输出:

A B C a b c d e f g
0 0 0 1 1 1 1 1 1 0
0 0 1 0 1 1 0 0 0 0
0 1 0 1 1 0 1 1 0 1
0 1 1 1 1 1 1 0 0 1
1 0 0 0 1 1 0 0 1 1
1 0 1 1 0 1 1 0 1 1
1 1 0 1 0 1 1 1 1 1
1 1 1 1 1 1 0 0 0 0

之后, 依旧是按照拆分的方式, 当然, 这次因为一方面输出的规则众多(8条规则), 另一方面输入也更多(三个), 像之前那种简单找规律已经不太灵光了, 我们也不打算再去仔细观察输入输出的规律, 就按机械方式来处理.

其实, 现在也很难找到什么规律, 比如 a-g 也没有完全一致的了, 单纯依靠一个输入就能决定的输出也很难去观察到(我也没有一一去仔细观察, 但现在数量如此之多, 想找到这种情况肯定更难了)

a 段

先看第一段 a 的情况:

A B C a
0 0 0 1
0 0 1 0
0 1 0 1
0 1 1 1
1 0 0 0
1 0 1 1
1 1 0 1
1 1 1 1

有 6 个为 1 的情况, 为 0 的只有两个. 前面说要找到那些为 1 的, 但目前的情况, 为 1 的太多, 为 0 的更少, 其实我们也可以反过来求出 !a, 最后再把结果反过来即可:

A B C a !a
0 0 0 1 0
0 0 1 0 1
0 1 0 1 0
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 0

如此一来, !a 只有两条为 1 的情况:

A B C a !a
0 0 1 0 1
1 0 0 0 1

一个是 001(数字 1), 一个是 100(数字 4), 据此, 可以写出表达式:

(!A · !B · C) | (A · !B · !C)

当然, 这个结果是 !a, 要得到 a, 再取一次反即可:

!((!A · !B · C) | (A · !B · !C))

取反的情况很多, 为减少非门的使用, 可以考虑应用 德摩根定律, 可以进一步化简:

!((!A · !B · C) | (A · !B · !C))
= !(!A · !B · C) & !(A · !B · !C) // 德摩根定律
= (A | B | !C) & (!A | B | C) // 德摩根定律

这样只有两处要取反, 据此, 即可画出对应门电路如下:

显示 a 段的逻辑电路

使用多输入门电路化简

因为有三个输入端, 这里用了两个 或门, 并把第一个或门的输出作为第二个或门的输入, 从而实现对三个输入 A B C 取或的操作.

显然, 即便有更多的输入, 不过是级联更多的门罢了, 问题总是可以解决的.

不过对于此种情况, 还有一种更简便的方式, 就是使用 多输入门电路.

在上述或门上双击(或 右键--属性), 在弹出的编辑属性窗口中, 找到 #输入 输入项, 把缺省的数字 2 改为 3, 即可调整为 三输入或门:

或门调整为使用三输入端

显然, 如果有更多输入的情况, 不过是把这个数字改为更大而已.

最终, 简化的电路如下:

显示 a 段的逻辑电路(使用三输入或门)

三输入的或门可以认为它内部封装了两个或门, 并以前述方式把第一个或门的输出作为第二个或门的输入连接起来, 最终暴露给我们的接口就是三个输入, 一个输出.

同理, 与门, 与非门, 或非门 乃至 异或门 都支持这种多输入的调整.

注意: 关于两输入 异或门, 我们先前说它能判断两个输入是否相同, 不过对于多输入异或门而言, 它的行为逻辑不是判断输入是否相同, 而是多个输入中是否含有 奇数 个 1(高电平).

这一结论对于两输入异或门同样成立, 所以异或门也常用于奇偶性判断.

你可以手动级联两个两输入异或门, 然后观察它的行为即可知道, 或者列举一下真值表也行.

根据逻辑代数定律进一步化简

在之前, 得到了一个 a 段的最终逻辑表达式为 (A | B | !C) & (!A | B | C), 我们说它是一个简化的结果, 但其实它还不是最简的.

清点一下, 不难发现, 这个逻辑式需要两个 非门, 两个三输入或门, 最后还要一个 与门 将结果综合起来, 也即总共 5 个门电路.

如果想进一步的化简, 就需要知道一些逻辑代数方面的定律, 我们前面也谈到了不少, 比如 德摩根定律, 还有交换律, 结合律, 互补律等.

为叙述的方便, 这里引入一种新的关于 与或非 的表达方式.

取反的新表达

常规的方式是 !A, 新的方式用 A', 也即是后接一个单引号;

取或的新表达

常规的方式是 A | B, 新的方式用 A + B, 因为 逻辑或 也叫 逻辑相加;

取与的新表达

常规的方式是 A & B, 新的方式用 A · B, · 表示 乘号, 因为 逻辑与 也叫 逻辑相乘;

最后, 乘号一般可以省略, 最终可以简写为 AB. 对于多个输入的情况, 这样会简化很多, 也不用使用太多括号.

具体化简例子

有了上述新的表达, 对于 a 段的逻辑表达式 (A | B | !C) & (!A | B | C), 可以写成:

(A+B+C')(A'+B+C)

然后, 逻辑代数有所谓 交换律, 交换一下, 得到:

(B+A+C')(B+A'+C)

这个交换的结论是很明显, 几乎无需证明.

然后, 逻辑代数还有 结合律:

  • A(BC)=(AB)C
  • A+(B+C)=(A+B)+C

以及 分配率:

  • A(B+C)=AB+AC
  • A+(BC)=(A+B)(A+C)

注意: 以上 A B C 既可以是单个的值, 也可以是一个复合的表达式.

这些的正确性都可以得到证明, 最简单的证明方式就是枚举出真值表, 一对比即可知.

应用 分配率, 对于前述表达, 可有:

 (B+A+C')(B+A'+C)
=B+(A+C')(A'+C) // 分配率第二条反过来运用, 提取公共的 B
=(B'((A+C')(A'+C))')' // 德摩根定律, 将 (A+C')(A'+C) 视为一个整体
=(B'((A+C')'+(A'+C)'))' // 德摩根定律
=(B'(A'C+AC'))' // 德摩根定律
=(B'(A⊼C))' // 注: A'C+AC' 就是 异或, 符号 `⊼` 表示异或操作.

最终结果是 A 和 C 取异或, 再与 B 的反 取与非.

也即需要一个 异或门, 一个 非门 和一个 与非门 总共三个门电路.

最终 a 段的电路可以进一步简化为:

显示 a 段的逻辑电路, 最简

e 段

再举另一个例子, e 段,

A B C e
0 0 0 1
0 0 1 0
0 1 0 1
0 1 1 0
1 0 0 0
1 0 1 0
1 1 0 1
1 1 1 0

为 1 的有三段:

A B C e
0 0 0 1
0 1 0 1
1 1 0 1

据此, 得出 A'B'C'+A'BC'+ABC' 的表达式.

其化简过程如下:

 A'B'C'+A'BC'+ABC'
=A'C'B'+A'C'B+ABC' // 交换律
=A'C'(B'+B)+ABC' // 分配率
=A'C'(1)+ABC' // 互补律
=A'C'+ABC' // 1·A=A, 1 与 任何值 A, 结果就是 A.
=C'A'+C'AB // 交换律
=C'(A'+AB) // 分配率
=C'(A'+B) // 逻辑代数公式: A+A'B=A+B, 证明见下文.
=(C+(A'+B)')' // 德摩根定律, 此处为减少非门的数量, 最后整体可以使用一个 或非门
=(C+AB')' // 德摩根定律

注: 上述用到一个逻辑代数公式: A+A'B=A+B. 如果不清楚为何是这样, 最简单的方式就是枚举所有情况, 因为 A 的情况无非也就两种: 0 或 1.

  • 假如 A = 0, 左边 A+A'B=0+1·B=0+B=B, 右边 A+B=0+B=B, 左边等于右边;
  • 假如 A = 1, 左边 A+A'B=1+0·B=1+0=1, 右边 A+B=1+B=1, 左边等于右边;

综上, 得证.

上述证明用到下述特性, 也是也显然无需证明的:

  • 0·A=0
  • 1·A=A
  • 0+A=A
  • 1+A=1

另, 此公式稍微变形即可得到: A'+AB=A'+B, 上面推演过程即应用了此变形.

最终, 需要一个 非门, 一个 与门, 一个 或非门 总共三个门电路.

显示 e 段的逻辑电路, 最简

遵循相同的步骤, 可以得出剩余的 5 段所需的电路, 具体的过程这里不一一展开, 最终的一个结果如下:

显示全部七个段的逻辑电路

这里有些电路或许也还不是最简的. 想要知道更多逻辑代数方面的公式与定律, 请参考相关教科书.

另: 除了公式化简法外, 其它一些化简方式还有:

  • 卡诺图化简法(Karnaugh Map)
  • 奎恩-麦克拉斯基化简法(Quine-McCluskey, 也称 Q-M 法)

读者可自行去了解, 这里不一一介绍.

显示一个先前未曾实现过的数字 4 的情况:

全部七个段的逻辑电路, 显示 4

事情至此也面临一个新的问题, 那就是整个电路非常之庞大(尽管已经一再简化). 假如后续还要塞入运算的部件, 还有显示两个加数的模块, 整个屏幕恐怕都无法显示.

在之前, 我们一直都有看到封装与抽象的威力及带给我们的好处, 比如 三输入或门 就封装了两个或门在其内部, 使得可以很简便地得到想要的功能.

更基础的, 如各种门电路, 都是对各种底层的继电器(或是晶体管)逻辑电路的封装.

假如没有这些门电路的封装, 目前实现的这个译码电路恐怕还要更为复杂. 现在的问题是, 能否进一步的去抽象与封装这个译码电路呢? 假如可以, 就可以把这一大堆组件及连接的细节隐藏到一个新的模块的内部, 后面想把两个加数与和都显示出来就简单了.

而这就要涉及到模拟器的一个新的功能: 创建子电路. 在下一章节, 将以译码电路为例, 探讨这一主题.

results matching ""

    No results matching ""