模拟电路可以利用三极管的导通 / 截止实现数字状态的切换,从而实现0和1的逻辑运算。
逻辑运算常用的有3种:与、或、非,它们都是1个二进制位的位运算。
在位运算的基础上,可以进一步实现加减运算。
位运算的特点是,多个位之间是无关的。
加减运算有进位和借位,多个位之间是相关的。
这里简单的给一下它们的电路:
1,与门,
电路,与门
1个电阻和2个二极管组成的与门,如上图。
2个二极管只要有1个导通(低电位0),输出电位就是0.7v,为低电位0。
0 & 1 == 1 & 0 == 0.
2个二极管都截止时(高电位1),输出等于电源电压,为高电位1。
1 & 1 == 1.
2,或门,
或门正好反过来,二极管接近电源正极,电阻接近电源负极。
电路,或门
2个二极管里只要有一个导通(高电位1),输出端就是高电位1。
1 | 0 == 0 | 1 == 1.
2个二极管都截止时,输出端是低电位0。
0 | 0 == 0.
二极管接到电源正极上就会导通,接到负极上就会截止。
3,非门,
非门,利用的是三极管的反相放大器。
当b极为高电位1时,三极管导通,电源电压大部分加在上拉电阻上,输出为低电位0。
反之,输出为高电位1。
电路,非门
位运算的电路都是很简单的,因为多个位之间不相关。
只要把多个电路并联起来,每个处理1个二进制位,就可以实现32位的运算。
4,加法,
加法因为有进位,比单纯的位运算要复杂一点。
0 + 0 = 0,
1 + 0 = 1,
0 + 1 = 1,
1 + 1 = 10,
二进制加法的前3种情况就是或运算,所以1个或门就可以处理前3种情况。
复杂的是1+1 = 10的情况,要处理进位:个位要变成0,十位要进位1。
主要说说这种情况:
下图是我随手画的二进制加法的电路
电路,加法
蓝色的电阻和2个向右的二极管组成或门,处理前3种情况:
0 + 0时,个位输出和三极管的b极都是0,结果为0;
0 + 1 == 1 + 0时,个位输出为1,三极管的b极为0,结果为1。
最后一种情况,1 + 1 == 10 时:
红色的电阻和2个向左的二极管组成与门,当2个加数都是1时,三极管的b极为高电位1,
这时三极管导通,三极管的c极为低电位0;
或门的输出为1,电流将沿着图中箭头的流向,经过三极管的c-e极流入电源负极,
个位输出与三极管的c极电压一样,为低电位0;
十位输出与三极管的b极电压一样,为高电位1。
这样就实现了1个二进制位的加法运算:1 + 1 = 10.
如果有多个二进制位,就把上图的电路并联起来,同时把(十位的)进位输出转到下一级的输入,继续更高位的运算。
位数越高电路越复杂,因为加法的各个位之间是可以进位的。
所以,在数字电路层面不适合处理复杂的逻辑,因为仅仅是加减乘除的实现就已经很复杂了。
所以,计算机的设计必然是分层的:
1)数字电路仅仅实现汇编代码级的逻辑,
2)更复杂的程序逻辑,放在C语言层面,
3)最复杂的逻辑,放在高级语言层面,毕竟C语言是个挂着高级语言的名头的大号汇编
如果不做分层设计,电子工程师要考虑的情况就太多了,需求的耦合度太大!
一旦耦合度大了之后,工程师们就会考虑分层分模块的设计。
编译器被分为词法、语法、语义、中间代码、机器码、目标文件生成、连接器,也是因为不这么划分的话耦合度太大了。
汇编代码难写,是因为它过于底层,与人类平时的思维方式差别很大。
但从数字电路的角度来看,汇编代码已经很上层了。