什么是格雷码
在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code)。
另外由于最大数与最小数之间也仅一位数不同,即“首尾相连”,因此又称循环码或反射码。由于这种特点,就可以避免二进制编码计数组合电路中出现的亚稳态。格雷码常用于通信,FIFO 或者 RAM 地址寻址计数器中。
格雷码属于可靠性编码,是一种错误最小化的编码方式,因为虽然二进制码可以直接由数/模转换器转换成模拟信号,但在某些情况,例如从十进制的 7 转换为 8 时二进制码的每一位都要变,能使数字电路产生很大的尖峰电流脉冲。而格雷码则没有这一缺点,它在相邻数字间转换时,只有一位产生变化。它大大地减少了由一个状态到下一个状态时逻辑的混淆。
从广义上讲,格雷码(Gray Code)不止一种,在没做特殊说明的情况下,格雷码是指经典格雷码。下面是深度为4的二进制码和格雷码的对照表。
二进制码 | 格雷码 | 二进制码 | 格雷码 |
---|---|---|---|
0000 | 0000 | 1000 | 1100 |
0001 | 0001 | 1001 | 1101 |
0010 | 0011 | 1010 | 1111 |
0011 | 0010 | 1011 | 1110 |
0100 | 0110 | 1100 | 1010 |
0101 | 0111 | 1101 | 1011 |
0110 | 0101 | 1110 | 1001 |
0111 | 0100 | 1111 | 1000 |
二进制码与格雷码的转换及其推理过程
我们将一个四位的二进制码 的四个位 分别设为A、B、C、D。
将上面表格中,格雷码的最低位等于0的情况的8种情况拿出来,
仅仅讨论格雷码的最低位,来列写逻辑函数
通过比较 图1 和 图3 ,B对于公式结果没有影响
比较 图5 和 图7,A对于公式结果没有影响,
所以 A 和 B 可以省去。
这时候再用上面的方式来列写 格雷码的最低位等于1的情况
不过我们已经知道了A、B对于公式没有影响,所以可以只列写C、D的情况
由于篇幅原因这里就不全部写出,仅列出一种情况,其他情况大家可以自己推导一下(不是因为我懒[doge])
这里直接给出结论:
我们将格雷码的最低位设为F,
通过 “根据 格雷码的最低位等于0的情况 所列写的公式”,可知:
(
(
C
)
′
+
(
D
)
′
)
∗
(
(
C
)
+
(
D
)
)
=
F
((C)' + (D)')*((C) + (D)) = F
((C)′+(D)′)∗((C)+(D))=F
再通过 “根据 格雷码的最低位等于1的情况 所列写的公式”,可知
(
(
C
)
′
∗
(
D
)
)
+
(
(
C
)
∗
(
D
)
′
)
=
F
((C)' * (D))+((C) * (D)') = F
((C)′∗(D))+((C)∗(D)′)=F
由上面两个式子可以得出
C
′
D
+
C
D
′
=
F
C'D+CD' = F
C′D+CD′=F
即
C
⨂
D
=
F
C\bigotimes D = F
C⨂D=F
然后按照相同的方法对格雷码的其他位进行分析
就可以得到二进制码转格雷码的方法:
从二进制码最右侧开始,依次向左,将一位与其左边一位相异或,
得到的数放入对应的位置,即可得到格雷码。
转码方式的核心思想
我们知道了转码方式,那为什么这样转码就可以产生相邻位转换仅变化一位的效果呢?
我们将6、7、8 三个的二进制数转化成波形图
可以观察到,“6”有两处“电平变换”,“7”有一处,“8”有两处。对比6和7,变换数量发生了变化,对比“6”和“8”,变换的位置发生了变化。再对比更多的二进制数,可以发现,每一个二进制数的“电平变换”的分布是独有的,而且这种分布在相邻的数之间仅差一位。(这仅仅是我观察得到的结论,还没有严谨的证明,有证明或证伪方法的朋友可以提出来)这用我们就可以用上面 相邻两位相异或的方式 来表示“电平变换”(上升沿和下降沿)的分布,就可以得到格雷码
其他转码方式
经典格雷码编码的核心思想就是通过某种运算来表示“电平变换”的分布,那还有什么方式可以产生同样的效果呢?
同或转换
就是将经典格雷码转码方式中的异或运算改为同或,这样可以得到经典格雷码的反码。
右侧异或
最右侧的最低位不变,从第二位开始,依次向左,位与右侧一位进行异或操作。当然,这样有一个问题,就是一个四位的二进制码很可能需要五位才可以表示,可能因此这种方法并不常用
格雷码的解码
这里以 经典格雷码(也就是一开始推导的)为例
首先找到格雷码的最高位,
格雷码的一位,与其上一位对应的二进制码相异或,
得到该位的二进制码,然后依次向右
如下图
至于这个公式是怎么来的…
等我什么时候不懒了就写推导过程
(前面推导过程那么详细,逆过程不是很难推…我觉得)