编码 | 解码 | 可视化

> 格雷码 | 反射 | 二进制 <

// 格雷码——一种相邻数值仅有一位二进制位不同的数字系统

0 字符
0 字符
[SINGLE-BIT]

单位距离

相邻编码之间仅有一位比特发生变化。

[ERROR-REDUCTION]

降低错误

在模数转换(ADC)等场景中减少读数抖动和误码。

[CYCLIC]

循环特性

首尾码字之间同样只相差一位比特,适合环形计数。

>> 技术细节

格雷码的工作原理:

格雷码(Gray Code,又称反射二进制码)是一种二进制编码方式,相邻两个数的码字只在一位上不同。常见生成方式是:将二进制数的每一位与其前一位做异或(XOR)。这种“单比特变化”特性在位置编码器、数字电路和抗干扰设计中非常有用。

格雷码示例:

Decimal | Binary | Gray Code
0       | 0000   | 0000
1       | 0001   | 0001
2       | 0010   | 0011
3       | 0011   | 0010
4       | 0100   | 0110
5       | 0101   | 0111
6       | 0110   | 0101
7       | 0111   | 0100

说明:任意相邻的格雷码之间只有 1 位不同

为什么使用格雷码:

  • ▸旋转编码器和位置传感器
  • ▸卡诺图(Karnaugh Map)化简
  • ▸数字通信中的差错控制
  • ▸鲁棒的状态机和计数器设计
  • ▸模拟量采集与量化过程中减少毛刺

>> 常见问题

什么是格雷码?

格雷码是一种相邻状态只变化一位二进制位的编码方式,又叫反射二进制码。与普通二进制计数相比,它能在状态切换时避免多位同时翻转,从而减少错误读数。

如何把二进制转换为格雷码?

转换规则:1)最高位保持不变;2)从次高位开始,每一位等于当前二进制位与前一位的异或。公式:G[i] = B[i] XOR B[i-1]。例如,二进制 1011 对应的格雷码是 1110。

为什么编码器喜欢用格雷码?

在纯二进制中,从 0111 到 1000 需要 4 位同时变化,如果传感器不同步,很容易在中间读到错误值。格雷码每次只翻转一位,大大降低了旋转编码器、滑块电位器等设备在边沿切换时的歧义。

格雷码常见的应用场景有哪些?

格雷码广泛应用于旋转编码器、卡诺图化简、数字通信调制与纠错、遗传算法中的染色体编码,以及各种需要避免“多位跳变”的计数器与采样系统。

// 速查表

DecBinaryGray
0000000
1001001
2010011
3011010
4100110
5101111
6110101
7111100

// 代码示例

Binary -> Gray   g = b ^ (b >> 1)
Gray -> Binary   b = g; for (m = g >> 1; m; m >>= 1) b ^= m;
Python           def to_gray(n): return n ^ (n >> 1)
                 def from_gray(g):
                     n = 0
                     while g: n ^= g; g >>= 1
                     return n
n bits           2^n codes, successive codes differ by exactly 1 bit (also 2^n - 1 -> 0)

>> 更多问题

问:什么是格雷码?

答:格雷码(反射二进制码)是相邻两个数值只相差一位的编码。由贝尔实验室的弗兰克·格雷申请专利,具有循环性:最后一个值与第一个值也只差一位。

问:为什么旋转编码器使用格雷码?

答:普通二进制在 011 到 100 这样的跳变时多位同时变化,若传感器切换不完全同步,会短暂出现错误值。格雷码每次只变一位,误差最多一个位置。

问:如何把格雷码转换为二进制?

答:最高位保持不变,之后每个二进制位等于前一个二进制位异或当前格雷码位。公式:b = g ^ (g >> 1) ^ (g >> 2) ^ …。二进制转格雷码则是 g = b ^ (b >> 1)。

其他语言