> 格雷码 | 反射 | 二进制 <
// 格雷码——一种相邻数值仅有一位二进制位不同的数字系统
单位距离
相邻编码之间仅有一位比特发生变化。
降低错误
在模数转换(ADC)等场景中减少读数抖动和误码。
循环特性
首尾码字之间同样只相差一位比特,适合环形计数。
>> 技术细节
格雷码的工作原理:
格雷码(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 位同时变化,如果传感器不同步,很容易在中间读到错误值。格雷码每次只翻转一位,大大降低了旋转编码器、滑块电位器等设备在边沿切换时的歧义。
格雷码常见的应用场景有哪些?
格雷码广泛应用于旋转编码器、卡诺图化简、数字通信调制与纠错、遗传算法中的染色体编码,以及各种需要避免“多位跳变”的计数器与采样系统。
// 速查表
| Dec | Binary | Gray |
|---|---|---|
| 0 | 000 | 000 |
| 1 | 001 | 001 |
| 2 | 010 | 011 |
| 3 | 011 | 010 |
| 4 | 100 | 110 |
| 5 | 101 | 111 |
| 6 | 110 | 101 |
| 7 | 111 | 100 |
// 代码示例
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)。