3、绝对式编码器原理:单圈与多圈、格雷码与二进制码、SSI协议基础
好,咱们今天聊聊绝对式编码器。这东西在工业现场太常见了,你想想看,一个机械臂回零,或者一个龙门铣的定位,靠的都是它。跟增量式那种一断电就“失忆”的编码器不同,绝对式编码器一上电就知道自己当前在哪个位置,不需要找参考点。这个特性,在很多安全要求高的场合,简直是救命稻草。
3.1 单圈与多圈:位置信息的“记忆”范围
先说说单圈和多圈。这个其实很好理解。
单圈绝对式编码器,说白了,它只能记住一圈之内的位置。比如一个360度的旋转轴,它告诉你现在在180度,那就是180度。但如果它转了两圈,它还是告诉你180度——它分不清这是第一圈还是第二圈。我刚开始接触这个的时候,就犯过这个错,以为它能记录圈数,结果调试时发现位置总对不上。
多圈绝对式编码器就不一样了。它内部有机械齿轮或者电子计数器,能记录旋转的圈数。比如一个4096圈的多圈编码器,它能记住从第1圈到第4096圈的每一个位置。嗯,这里要注意:多圈编码器的圈数是有上限的,不是无限的。你想想看,如果它转了一万圈,超过了设计上限,那它就会溢出,位置信息就乱了。
我个人习惯,在需要长期连续运行的设备上,比如输送带或者旋转工作台,我会优先选多圈编码器。单圈编码器更适合那些只在有限角度内运动的场合,比如阀门控制。
| 类型 | 位置范围 | 典型应用 |
|---|---|---|
| 单圈 | 0° ~ 360° | 阀门、云台、小角度摆动 |
| 多圈 | 多圈(如4096圈) | 机械臂、数控机床、旋转工作台 |
3.2 格雷码与二进制码:为什么工程师偏爱格雷码?
接下来是编码方式。绝对式编码器输出的位置信息,通常有两种编码形式:二进制码和格雷码。
二进制码,就是咱们熟悉的0和1。比如位置100对应二进制1100100。听起来很直接,对吧?但这里有个坑。当编码器从一个位置切换到相邻位置时,比如从0111(7)到1000(8),二进制码的多个位会同时变化。如果读取的瞬间,各个位的切换速度不一致,就可能读到错误的值,比如读到1111或者0000。我在一个高速旋转的电机上遇到过这个问题,位置数据跳得离谱,后来排查才发现是二进制码的“毛刺”导致的。
格雷码就是为解决这个问题而生的。它的特点是:相邻两个位置之间,只有一位二进制数发生变化。比如从7(格雷码0100)到8(格雷码1100),只有最高位变了。这样,即使读取的时机不完美,最多也就错一个位,误差很小。我建议,在高速或者干扰大的场合,优先用格雷码。
格雷码和二进制码之间可以互相转换。下面是一个简单的转换函数,我在项目里经常用:
// 二进制转格雷码
uint16_t bin2gray(uint16_t bin) {
return bin ^ (bin >> 1);
}
// 格雷码转二进制
uint16_t gray2bin(uint16_t gray) {
uint16_t bin = gray;
while (gray >>= 1) {
bin ^= gray;
}
return bin;
}
你看,代码很简单。但要注意,格雷码转二进制需要循环,如果位宽很大(比如32位),这个循环可能会影响实时性。我曾经在一个项目中,用查表法代替循环,速度提升了不少。
3.3 SSI协议基础:同步串行接口
最后说说SSI协议。这是绝对式编码器最常用的通信接口之一。SSI的全称是Synchronous Serial Interface,同步串行接口。它用时钟线和数据线两根线,就能把位置信息传出来。
SSI的通信过程是这样的:主设备(比如PLC或者运动控制器)发送一串时钟脉冲,编码器在每一个时钟的上升沿或下降沿,同步输出一位数据。数据通常是格雷码格式的。我习惯用上升沿采样,这样时序比较稳定。
下面是一个典型的SSI时序图,我用SVG画了一下,方便你理解:
你看,时钟线CLK每来一个脉冲,数据线DATA就输出一位。数据位从高位到低位依次输出。SSI协议还有一个特点:它支持多圈编码器,数据帧里既包含单圈位置,也包含圈数信息。
关键点总结:
- 单圈编码器只记录一圈内的位置,多圈编码器记录圈数和圈内位置。
- 格雷码相邻位置只有一位变化,抗干扰能力强,是工业现场的首选。
- SSI协议用时钟同步数据,简单可靠,适合长距离传输。
我的小技巧: 在调试SSI通信时,先用示波器抓一下时钟和数据线的波形。看看时钟频率是否稳定,数据位是否对齐。我曾经因为时钟线太长,导致信号反射,数据读出来全是乱的。后来加了终端电阻,问题就解决了。
注意: 绝对式编码器的数据输出频率不能太高。如果时钟频率超过编码器的最大支持频率,数据可能会出错。我建议,时钟频率不要超过编码器手册中规定值的80%,留点余量。
好了,关于绝对式编码器的原理,咱们就聊到这儿。单圈与多圈的选择、格雷码与二进制码的取舍、SSI协议的时序,这些都是实际项目中绕不开的点。你只要把这些搞清楚了,后面处理编码器数据就会顺手很多。