尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

STM32伺服编码器接口选型:多摩川绝对值与BiSS-C实战解析

STM32伺服编码器接口选型:多摩川绝对值与BiSS-C实战解析 做伺服这几年我最大的感受是很多同仁一开始接触运动控制都是从ABZ编码器入门的用STM32定时器做正交解码读A相B相Z相逻辑简单、资料也多。可真到了伺服项目落地阶段面对多摩川TAMAGAWA绝对值编码器、BiSS-C这种串行绝对值接口时ABZ那套思维往往直接卡壳——不是读不出数据而是不知道该怎么选、怎么接、怎么把位置可靠地拿回来。这篇文章不扯没用的直接用我实际调试伺服项目的经验把STM32伺服项目里编码器接口的选型逻辑、多摩川绝对值编码器的读取方法、BiSS-C主站实现的关键细节一次讲透。内容适合正在做伺服驱动器、运动控制卡、机器人关节模组或者准备把ABZ方案升级到绝对值方案的工程师。看完你至少能回答三个问题我的项目到底该用什么编码器接口多摩川编码器怎么用STM32读BiSS-C时序到底怎么抓1. 同样是编码器为什么ABZ会在伺服项目里“不够用”1.1 增量编码器与绝对值编码器的本质差别ABZ的本质是增量式方波输出A相和B相位差90度用来判断方向和计数Z相每转一圈输出一个零位脉冲用来辅助回零。用STM32定时器做正交解码非常方便配置成Encoder Mode后计数器会自动根据A/B相位关系加减Z相可以用外部中断或者定时器从模式清零。这套方案的痛点在于它丢失了一个关键信息——断电位置。电机一掉电位置就只剩计数器里的值只要有一个干扰脉冲、一次上电抖动、一次手动盘车当前位置就废了。伺服系统要求的位置闭环、力矩闭环都建立在“当前位置可信”这个前提下。ABZ一旦受到干扰哪怕只是几微秒的毛刺位置就跳变几个脉冲轻则抖动重则飞车。绝对值编码器解决的就是这个问题。它通过光电或磁电方式在上电瞬间就能输出当前绝对位置不需要回零动作。日系的多摩川TAMAGAWA编码器在伺服电机上一体化封装非常普遍很多国产伺服电机标的“17位绝对值”“23位绝对值”实际用的就是多摩川或者对标多摩川的编码器。它的输出不再是简单的方波而是通过SPI、异步串行或者BiSS-C这类协议把位置数据、圈数数据、报警状态、CRC校验一起打包传出来。1.2 伺服项目对编码器接口的四个硬性要求我这些年做伺服相关项目总结下来编码器接口选型就看四点。第一上电即知位置。这点ABZ做不到普通增量编码器上电必须回零如果设备没有原点开关或者机构不允许上电乱动ABZ就很尴尬。绝对值编码器尤其是带多圈的上电直接读出位置省掉回零动作这在机器人和高端设备上是刚需。第二抗干扰能力。ABZ是脉冲信号电平跳变沿就是信息一根线被干扰抖动一下位置就丢。串行绝对值接口把数据按帧传输带CRC校验错误帧能被识别出来可靠性高一个量级。第三闭环带宽。伺服位置环、速度环跑得稳不稳取决于编码器数据更新的实时性。ABZ靠计数实时性其实不差但串行绝对值编码器如果时钟频率低、帧长又长位置更新率可能拖后腿这在选型时容易被忽略。第四扩展信息。温度、报警、多圈计数、ID信息这些ABZ完全给不了。BiSS-C、多摩川这类协议可以在数据帧里带上状态位和寄存器区驱动器和上位机能直接读到编码器健康状态。一句话总结如果你的项目是演示、学习、简单定位用ABZ够用如果是真正的伺服闭环、工业设备、机器人关节建议认真考虑绝对值接口。这也是我为什么要专门写多摩川和BiSS-C而不是继续教ABZ。2. 多摩川编码器接口解析STM32侧的读取思路2.1 多摩川编码器常见形态与引脚定义多摩川TAMAGAWA SEIKI是日系编码器老牌厂商它的绝对值编码器在伺服电机里占有率非常高。外观上就是电机尾部那个圆盘形模块引出线常见6针或8针。引脚基本包括电源正、电源地、数据线、时钟线或片选有的还有报警输出。这里有个关键认知多摩川绝对值编码器的“接口”不是只有一种。我实际遇到过三类——SPI类、异步串行类、BiSS-C类。老型号和部分国产替代型号以SPI为主SCLK、DATA、CS三根线主机发时钟从机回数据。异步串行类则像UART一样一根线收发数据。近年的新项目里BiSS-C越来越多多摩川也有直接支持BiSS-C的型号但很多工程师还停留在“多摩川SPI读一圈数据”的认知里遇到BiSS-C版本就懵了。所以拿到编码器第一件事不是写代码而是查型号数据手册确认它是哪类接口。手册里一般会给出时序图、数据帧格式、位宽、校验方式。这一步比写驱动还重要因为多摩川这类编码器不同批次、不同型号之间寄存器格式和位定义可能存在差异。2.2 用STM32 SPI读取多摩川绝对值位置以最常见的SPI类多摩川绝对值编码器为例读取思路其实不复杂CS拉低使能SCLK提供时钟DATA线在时钟边沿输出数据位。STM32做主机SPI外设天然合适。不过有几个坑要提前说。第一数据位宽不一定是标准的8位或16位很多多摩川编码器单圈是17位、23位加上圈数和状态位后总长度可能是32位甚至更长SPI硬件数据寄存器不一定能一次读完需要分字节读或者用DMA拼帧。第二时钟极性和相位必须按手册配有的编码器要求在SCLK上升沿移出数据、下降沿锁存SPI的CPOL和CPHA配反了读出来的数据就是乱的。第三CS片选时序要干净CS拉低后要留出t_setup时间读完也要留出t_hold不能刚拉低就给时钟。我给出一个简化的读取框架// 以32位数据帧为例 uint32_t tamagawa_read_position(void) { uint32_t raw 0; // 片选拉低启动一次通信 HAL_GPIO_WritePin(ENC_CS_GPIO_Port, ENC_CS_Pin, GPIO_PIN_RESET); // 根据实际帧长度决定读取字节数这里假设4字节 // SPI通信时主机发送任意时钟从机在MISO上返回数据 // 注意多摩川SPI类编码器可能要求主机时钟频率有上限一般不超过几MHz uint8_t b0 spi_read_write_byte(0x00); uint8_t b1 spi_read_write_byte(0x00); uint8_t b2 spi_read_write_byte(0x00); uint8_t b3 spi_read_write_byte(0x00); HAL_GPIO_WritePin(ENC_CS_GPIO_Port, ENC_CS_Pin, GPIO_PIN_SET); raw ((uint32_t)b0 24) | ((uint32_t)b1 16) | ((uint32_t)b2 8) | (uint32_t)b3; return raw; }这段代码只是骨架真正用时需要根据手册把帧里的符号位、状态位、圈数位、位置位重新拆解。有些型号数据里还带CRC或奇偶校验解析前一定要先做校验别直接把raw当成位置用。2.3 格雷码转换、多圈处理与断电记忆多摩川编码器很多型号输出的是二进制码但也有部分输出格雷码。格雷码的特点是相邻位置只有一位变化抗干扰能力强但软件上必须转换成二进制才能用。格雷码转二进制的公式很简单从最高位开始bin[i] bin[i-1] ^ gray[i]也就是二进制的每一位等于上一位二进制值异或当前格雷码位。这个转换在STM32上开销很低用循环或查表都行但千万别忘了否则位置会以奇怪的方式跳变。多圈处理的逻辑也很关键。多圈编码器的原始帧里通常包含两部分单圈位置例如17位和多圈计数例如16位。读取后先确认圈数位不是全0或全1的异常状态再把两者拼成一个完整绝对位置。有了圈数断电后再上电只要编码器没有超出多圈量程位置就是连续的这就是“断电记忆”的底层实现。它不需要外部电池靠编码器内部机械或磁性的多圈计数机制完成。我在实际项目里踩过一个坑某型号多摩川编码器单圈是23位但帧里还插了3个状态位和若干错误标志我没仔细看帧格式直接把整个32位当成位置导致每圈结尾位置跳变一大截。后来用示波器一帧一帧数位才定位到是解析位偏移的问题。这种问题写代码时很难发现必须对照手册里的位序图仔细核对。3. BiSS-C接口实操STM32上的主站实现3.1 BiSS-C的通讯过程到底长什么样BiSS-C是iC-Haus推出的开放协议这些年几乎成了伺服编码器接口的默认选项之一。它本质上是同步串行通信主站输出MA时钟从站通过SLO数据线同步回传数据。协议本身是开源的不需要授权费所以越来越多编码器厂商支持它。很多第一次接触BiSS-C的人会被帧结构吓到其实拆开看没那么玄。一帧数据大致包含空闲态MA保持高电平SLO也保持高电平Start位MA拉低至少一个时钟周期告诉从站准备发送ACK位从站回应CDS字段主站发送控制数据用于读寄存器、写参数一位START分隔位SDS字段从站回传主要数据也就是位置、圈数、状态这些具体内容CRC字段通常是6位CRC校验通讯过程中主站负责提供MA时钟从站在时钟驱动下逐位输出SLO数据。位置数据和状态数据都在SDS段里CRC则保证了整帧数据没有被干扰污染。一开始我也觉得BiSS-C时序要求高必须上FPGA或者专用芯片。后来真正在STM32上调通了才发现只要把MA时钟和SLO采样逻辑理顺普通MCU完全能扛住。重点是理解什么时候锁存数据、什么时候读取SLO、怎么拼帧和校验。3.2 定时器时钟 GPIO采样的低成本主站方案在STM32上实现BiSS-C主站我推荐一个低成本、容易调通的方案用定时器PWM输出作为MA时钟SLO数据线接到普通GPIO在MA时钟的下降沿或根据编码器手册指定的采样边沿去读取SLO电平逐位拼接成帧。这个方案的优点是不依赖SPI外设的帧格式限制帧长短一点没关系什么时候开始、什么时候结束都由自己控制。缺点是如果只用GPIO中断逐位采样中断频率太高会占用CPU。我实际用的做法是定时器输出5MHz~10MHz的PWM作为MASLO接到有EXTI能力的引脚在下降沿中断里读一位数据。如果是32位位置加上CRC和状态位一帧可能50位左右一帧读下来大约几十微秒对伺服控制周期来说可以接受。伪代码的思路是volatile uint32_t biss_frame[2]; // 64位缓冲区按位填充 volatile uint16_t bit_count 0; void EXTI_slo_irq_handler(void) { // 在MA下降沿触发此时SLO上的数据位已经稳定 uint8_t bit_val (uint8_t)HAL_GPIO_ReadPin(ENC_SLO_GPIO_Port, ENC_SLO_Pin); if (bit_count 64) { if (bit_val) { biss_frame[bit_count 5] | (1UL (31 - (bit_count 31))); } else { biss_frame[bit_count 5] ~(1UL (31 - (bit_count 31))); } bit_count; } }如果不想占用CPU也可以用定时器触发DMA采样SLO引脚电平DMA把每个MA周期的SLO电平存进缓冲区主循环再解析。STM32的DMA触发源有限需要查一下所选型号的DMA请求映射这在F1、F4、H7系列上不太一样。这个方案里最容易出问题的是采样边沿。有些BiSS-C编码器要求在MA上升沿数据锁存有些要求在下降沿输出稳定采样边沿选错读回来的数据就是对不齐的乱码。我建议先看编码器手册中的时序图确认SLO相对于MA是哪个边沿变化然后在MA的另一个边沿采样。如果没有手册我一般先默认下降沿采样再用示波器对比数据是否正确。3.3 CRC校验、寄存器操作与初始化时序BiSS-C帧末尾一般带6位CRC用CRC-6多项式常见多项式是0x43x^6x1。计算范围一般从START位之后开始覆盖CDS和SDS的数据位不包括CRC本身。不同编码器实现对CRC初始值、是否取反可能有差异这个必须看手册不能想当然。CRC校验的核心作用是防止错误帧被当成真实位置用。伺服系统里位置数据一旦错了后果可能是电流指令突变甚至飞车。所以我的原则是CRC不过这帧数据直接扔掉保留上一次有效位置连续多帧CRC错误则触发编码器故障报警而不是盲目继续跑。寄存器操作则是BiSS-C进阶玩法。CDS字段除了通信还可以携带寄存器地址、读写命令和数据。比如读取编码器ID、读取温度、设置电子零点、写圈数预置值这些都能通过寄存器模式实现。但在实时伺服运行中寄存器访问会占用CDS和SDS之间的时间槽影响位置数据的更新率所以我的建议是上电初始化阶段做寄存器读写正常运行时只读位置帧保持实时性。初始化时序也要注意。编码器上电后往往需要一段时间完成内部状态准备手册里一般会写“power-on time”或“startup time”。我之前调试时遇到过一上电就立刻发MA时钟编码器不响应的现象后来确认就是上电时间不够。解决方法是上电后延时几十毫秒到几百毫秒再开始通信同时先发几帧空数据让编码器同步再解析有效位置。4. 多摩川、BiSS-C与ABZ伺服接口选型对比4.1 三者在信号线、实时性、可靠性上的差异做了这么多项目我发现很多人选型时只看协议名字不看实际信号特征导致画板时发现引脚不够、布线困难。这里我直接给一张对比表方便大家按需选用。维度ABZ增量多摩川绝对值BiSS-C信号线数量A、B、Z三路脉冲多数为CLK/DATA两路或SPI三线MA/SLO两路上电是否回零需要不需要不需要多圈位置不支持支持支持数据校验无部分型号带CRC/奇偶校验固定CRC校验实时性高硬件计数取决于时钟频率和帧长高时钟由主站决定抗干扰能力一般脉冲易受干扰较强串行帧带校验强差分传输更稳调试难度低中中高应用场景学习、简单定位伺服电机集成方案高端伺服、机器人、直驱单看信号线这点ABZ要三路多摩川和BiSS-C都是两路省IO不是重点重点是差分传输的可行性和抗干扰能力。BiSS-C在工业现场经常配合RS422差分收发器跑长线而ABZ一般只能做短距离脉冲传输距离一长、干扰一大位置就跳。4.2 不同伺服项目该优先考虑哪种接口我个人的选型经验是这样的如果是做学习用的小型伺服驱动器、桌面小运动平台ABZ完全可以。STM32定时器编码器模式处理ABZ非常成熟调试工具也多适合起步。如果产品定位是通用伺服、需要上电免回零、又要兼容电机尾部的一体化编码器那么多摩川绝对值编码器是很好的选择。因为市面上大量伺服电机标配就是多摩川编码器采购容易供应商资料也全。对多数国产伺服项目来说“电机带多摩川编码器”几乎等于标准配置。如果做的是高性能伺服、直驱电机、机器人关节或者对位置刷新率、数据可靠性要求更高的场景BiSS-C是更面向未来的选择。它的协议开放编码器厂商多帧结构可以按需扩展前端还能做差分抗干扰更强。缺点是需要投入一定时间熟悉协议和调试不像ABZ那样开箱即用。还有个容易被忽略的选型变量是供应链。ABZ编码器谁都能做但真正稳定的绝对值编码器尤其是多摩川这种原厂货供货周期和价格会出现波动。BiSS-C也在逐渐普及但不同厂商的寄存器表、帧长定义有差异换供应商后驱动要重新适配。所以选型时除了看技术参数最好把供应商能提供的调试资料、例程支持也纳入考量。5. 实战中的常见问题与排查技巧5.1 编码器读不到数据时的排查顺序碰到的第一个问题往往都是“什么都读不回来”这时候不要急着改代码先按顺序排查。先看供电。绝对值编码器对电源要求比较高纹波大、电压不够都会导致通信异常。用万用表量编码器供电端的电压最好现场用示波器看纹波有些板子空载电压正常一带编码器就掉电这种问题最容易漏。再看时序和电平。打开示波器同时抓CLK/MA和DATA/SLO确认主站确实发出了时钟、从站有没有在数据线上输出信号。如果时钟有、数据线一直是高或一直是低很可能是片选没拉对或者编码器根本没进入通信状态。如果是BiSS-C先确认MA空闲是不是高电平有些从站对空闲电平有要求空闲电平不对帧同步就建立不起来。最后看共地。编码器地和MCU地必须连在一起很多“偶发读不到数据”最后查出来就是地没共好或者用了两个电源导致地电位差。5.2 数据异常跳变、CRC报错的常见诱因数据能读到但偶尔跳变或者CRC频繁报错这种情况比完全读不到更难排查。我整理了几个最常见的诱因线缆过长且未做差分。BiSS-C在短距离内单端也能跑但线一长干扰就上来了。我建议超过20厘米的编码器线就走差分传输用RS422收发器如AM26LV32/AM26LV31这一类把MA和SLO转成差分信号。数据线要双绞屏蔽层单端接地不要和电机动力线走同一个线槽。时钟频率过高。编码器手册会给出MA时钟的上限比如5MHz、10MHz或者更高。我在调试某款BiSS-C编码器时把MA从5MHz提到10MHz后发现CRC错误率明显上升降回8MHz以下就稳定了。不是所有编码器都能按标称上限跑线缆电容、接收器速率都会降低实际可用频率。采样边沿不对。BiSS-C采样边沿选错表现是数据帧结构是对的但位置的某些位固定错乱或者位置呈现周期性跳变。回到时序图找到SLO相对于MA的建立时间和保持时间再调整采样边沿。5.3 几个被忽略的硬件细节编码器信号通常是小电流、高频率的数字信号而伺服驱动器里又有大电流功率管两者在同一个板子上布局布线要格外小心。我把编码器接口座尽量放在驱动器板子的低压侧远离功率管和电流采样电阻。编码器的电源使用独立的LDO或者DC-DC不要直接从功率级电源拉避免功率级开关噪声污染编码器供电。另外很多绝对值编码器的IO电平是3.3V或5V如果编码器是5V逻辑而STM32是3.3V需要做电平转换不能直接接。BiSS-C差分方案里收发器的电平匹配也要提前确认。我还养成了一个习惯所有编码器帧的解析代码里都加一个“帧格式打印”调试开关在样机阶段把原始帧打印出来对曲线、对波形。这个开关帮助我解决了很多“看起来对但实际错位”的难题。等到确认帧格式稳定了再关掉打印避免影响实时性。关于编码器数据更新还有一个小建议。如果你在STM32上做FOC或者伺服位置环不要把编码器读取放在中断里硬实时读取而是采用“双缓冲”或“DMA预取”的方式编码器数据准备好后更新到一个全局结构体里控制环在周期开始时直接取用最近一帧位置。这样可以避免SPI或GPIO读取过程中被控制周期打断导致位置数据半新半旧。最后分享一个我自己的习惯拿到新编码器样品第一件事不是写驱动而是用示波器把MA/SLO或者CLK/DATA的波形抓出来一帧一帧数清楚确认起始位、数据位、CRC位分别在哪里。把这个搞明白再回MCU写代码基本一遍过。踩过几次坑之后你会认同编码器接口调试最大的敌人不是协议本身而是你对波形细节的耐心程度。
返回列表