4、绝对式编码器详解:单圈与多圈、格雷码与二进制码、SSI与BISS通信协议、位置读取流程

各位工程师朋友,今天我们来聊聊绝对式编码器。说实话,这玩意儿在工业现场的地位,就跟人的记忆一样——断电了还能记住自己站在哪儿。增量式编码器一断电就失忆,而绝对式编码器不会。我最早接触它是在一个龙门铣床的项目上,设备每次上电都要回零,操作工烦得要命。后来换成绝对式,开机直接用,那感觉,真香。

4.1 单圈与多圈:你到底能转多少圈?

绝对式编码器分两种:单圈和多圈。单圈的,说白了就是一圈之内能告诉你精确位置。比如一圈有1024个位置,那它就能分辨到1/1024圈。但如果你转了一圈又一圈,它就懵了——因为它只记得自己在这一圈里的位置,不记得这是第几圈。

多圈就不一样了。它内部有机械齿轮或者电子计数器,能记录你转了多少圈。我见过一个多圈编码器,能记录4096圈,每圈又有8192个位置。你想想看,这精度和范围,用在机器人关节上绰绰有余。

选型要点:

  • 单圈:适用于旋转角度不超过360°的场景,比如阀门开度检测
  • 多圈:适用于需要记录多圈旋转的场景,比如机械臂关节、数控机床主轴
  • 注意:多圈编码器的圈数记录有上限,超过会溢出,需要复位

4.2 格雷码与二进制码:为什么工程师偏爱格雷码?

绝对式编码器输出的位置数据,可以用二进制码,也可以用格雷码。二进制码我们都很熟悉,但格雷码你可能不太常用。格雷码有个特点:相邻两个数值之间,只有一位发生变化。

为什么会这样?我举个例子。二进制码从7(0111)变到8(1000),四位全变了。如果编码器刚好在这个边界上,由于机械或电气误差,可能读出0111、1000或者中间态,那位置就完全错了。而格雷码相邻值只变一位,就算有误差,最多错一个位置。

我在一个伺服驱动器项目里吃过这个亏。当时用了二进制码的编码器,结果在零点附近位置跳变,电机跟着抖。后来换成格雷码,问题就解决了。嗯,这里要注意:格雷码虽然抗干扰好,但直接计算位置不方便,需要转换成二进制码。

十进制 二进制码 格雷码
0 0000 0000
1 0001 0001
2 0010 0011
3 0011 0010
4 0100 0110
5 0101 0111
6 0110 0101
7 0111 0100
8 1000 1100

格雷码转二进制的小技巧:最高位保留,然后从高位到低位,每一位等于前一位二进制值与当前格雷码异或。代码实现很简单,但现场调试时手算也很快。

4.3 SSI与BISS通信协议:谁更快?谁更稳?

绝对式编码器怎么把位置数据传给控制器?最常用的两种协议是SSI和BISS。SSI是同步串行接口,BISS是它的升级版。

SSI协议,我习惯叫它「老黄牛」。稳定、可靠、简单,但速度一般。它用时钟线和数据线,主设备发时钟,编码器在时钟上升沿或下降沿输出数据。数据格式一般是:起始位 + 位置数据 + 状态位 + 校验位。我曾经用SSI接过一个24位的编码器,时钟频率跑到1MHz,读取一次位置大概要25微秒,够用。

BISS协议就不一样了。它也是串行,但支持更高的时钟频率,而且有CRC校验。BISS C模式更是把时钟频率推到10MHz以上。你想想看,同样的24位数据,BISS读取一次只要2.5微秒,快了十倍。我在一个高速贴片机项目里用过BISS,编码器反馈延迟几乎可以忽略。

注意:BISS虽然快,但对线缆和接口要求高。线太长或者屏蔽不好,高频信号容易出问题。我曾经在一条10米长的线缆上跑BISS,结果CRC错误率飙升。后来换成专用屏蔽双绞线,问题才解决。

4.4 位置读取流程:从硬件到软件

好了,理论说完了,我们来点实际的。一个完整的位置读取流程,大概分这几步:

  1. 初始化通信:配置SPI或专用接口,设置时钟频率、数据格式
  2. 发送请求:主设备发送时钟信号,编码器开始输出数据
  3. 接收数据:按协议解析数据帧,提取位置值
  4. 校验数据:检查校验位或CRC,确保数据正确
  5. 转换格式:如果是格雷码,转成二进制;如果是多圈,合并圈数和圈内位置
  6. 输出位置:将最终位置值传给运动控制算法

下面是一个SSI读取的代码示例,我用的是STM32的SPI接口:

// SSI读取绝对式编码器位置
uint32_t ReadSSI_Position(void)
{
    uint32_t raw_data = 0;
    uint8_t i;
    
    // 1. 拉低片选,开始通信
    HAL_GPIO_WritePin(SSI_CS_GPIO_Port, SSI_CS_Pin, GPIO_PIN_RESET);
    delay_us(1);  // 等待编码器准备
    
    // 2. 发送时钟,读取数据(假设24位数据 + 1位校验)
    for(i = 0; i < 25; i++)
    {
        HAL_GPIO_WritePin(SSI_CLK_GPIO_Port, SSI_CLK_Pin, GPIO_PIN_SET);
        delay_us(1);
        raw_data <<= 1;
        if(HAL_GPIO_ReadPin(SSI_DATA_GPIO_Port, SSI_DATA_Pin) == GPIO_PIN_SET)
        {
            raw_data |= 0x01;
        }
        HAL_GPIO_WritePin(SSI_CLK_GPIO_Port, SSI_CLK_Pin, GPIO_PIN_RESET);
        delay_us(1);
    }
    
    // 3. 拉高片选,结束通信
    HAL_GPIO_WritePin(SSI_CS_GPIO_Port, SSI_CS_Pin, GPIO_PIN_SET);
    
    // 4. 提取位置数据(高24位)和校验位(最低位)
    uint32_t position = (raw_data >> 1) & 0x00FFFFFF;
    uint8_t parity = raw_data & 0x01;
    
    // 5. 简单校验:奇校验
    uint8_t calc_parity = 0;
    for(i = 0; i < 24; i++)
    {
        calc_parity ^= (position >> i) & 0x01;
    }
    if(calc_parity != parity)
    {
        // 校验失败,返回错误码
        return 0xFFFFFFFF;
    }
    
    return position;
}

调试经验:第一次调SSI时,记得用示波器抓时钟和数据线。我遇到过时钟极性设反的情况,数据全错。另外,片选信号的时序也很关键,太短编码器来不及响应,太长又影响读取速度。

4.5 知识体系总览

为了让你更直观地理解本章的知识结构,我画了一张图:

绝对式编码器知识体系 分类 编码方式 通信协议 单圈 多圈 二进制码 格雷码 SSI BISS 核心特性:断电记忆位置、抗干扰、高精度 位置读取流程 初始化通信 发送请求 接收数据 校验数据 输出位置

这张图把绝对式编码器的核心知识点串起来了。从分类到编码方式,再到通信协议,最后落到实际的位置读取流程。我个人建议你把它打印出来贴在工位上,调试的时候看一眼,思路会清晰很多。

好了,这一章的内容就到这里。绝对式编码器虽然比增量式贵一点,但省去的回零操作和抗干扰能力,绝对值回票价。下一章我们会聊编码器的选型实战,到时候我会分享一些具体的型号对比和成本分析。


公众号:蓝海资料掘金营,微信deep3321