ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

西门子PLC与汇川伺服Modbus-RTU通讯实战解析

2026/10/6 16:34:13 拓冰建站 浏览量
西门子PLC与汇川伺服Modbus-RTU通讯实战解析 车间里一台老设备改造客户提了个要求别加运动控制卡就用PLC上闲置的那个485口把伺服带起来。我第一反应就是汇川伺服加Modbus-RTU——不用额外买通讯板卡不用换驱动器一条双绞线就能让西门子PLC和汇川伺服对上话。这篇文章就把我从Modbus-RTU帧结构解析、汇川伺服参数设置到西门子PLC侧程序配置的完整过程记录下来算是一份能直接参考复现的实战文档。适合正在做设备改造、维护调试或者刚接触伺服总线通讯的工程师。很多朋友一听到“总线通讯”就发怵觉得协议高深莫测。实际把Modbus-RTU拆开看无非就是按固定格式发一串16进制字节伺服收到后回一串字节仅此而已。真正干活时让人卡壳的往往是几个细节CRC校验怎么算、寄存器地址从哪查、PLC里那个ADDR参数怎么拼、伺服使能后为什么不动。这些我都会在下面逐个讲透。1. 方案选型为什么是Modbus-RTU1.1 汇川伺服的主流通讯方式对比汇川伺服驱动器以常见的IS620N系列为例本身支持脉冲、CANopen、EtherCAT、Modbus-RTU等好几种控制方式。选型时很多人纠结我直接给一张对比表大家按场景对号入座。控制方式通讯/信号介质典型周期成本适用场景脉冲脉冲方向信号实时性取决于发脉冲频率最低无需通讯模块简单单轴定位PLC高速脉冲口够用CANopenCAN总线1-10ms中多轴中小型设备PLC带CAN口EtherCAT以太网0.125-1ms较高多轴高速高精度需要专用主站Modbus-RTURS48510-50ms取决于轮询低老设备改造、少轴点位控制、PLC仅支持串口从成本角度讲Modbus-RTU几乎不增加硬件成本。PLC自带RS485口或加一个几十块的通讯板伺服用标准RJ45或端子接线两边拨码一拨就完事。对于老设备改造、单轴或两三轴的点位控制这种方案性价比极高。1.2 Modbus-RTU的性能边界Modbus-RTU不是万能的它的性能边界得说清楚免得大家踩坑。RS485串口通讯常见波特率9600或19200算一帧十几字节的数据再加上帧间隔主站轮询一个从站大约要5-10ms。如果你带三五台伺服完整轮询一圈可能到30-50ms。这个响应速度做点位运动控制、速度控制、状态监控完全够用但要做多轴插补、高速高精轮廓加工那就别指望它了老老实实上EtherCAT。还有一点要注意Modbus-RTU是半双工主从协议所有通讯由主站发起从站之间不能直接通讯。这意味着你的控制逻辑必须集中在PLC侧伺服侧的“联动”需要通过PLC轮询来实现。好在汇川伺服大部分运动控制是“给目标位置、触发运行”这种点位模式天然适合Modbus-RTU。1.3 硬件准备与组网拓扑本次实战所用硬件清单如下汇川伺服驱动器IS620N一台配套伺服电机MS1H4系列西门子S7-1200 PLC一台外加CM1241 RS485通讯模块订货号6ES7241-1CH30-1XB0USB转RS485调试工具一个用于先单独验证伺服通讯屏蔽双绞线若干米RS485通讯线组网拓扑很简单PLC的CM1241模块的RS485口作为主站用屏蔽双绞线引出A、B两线接到伺服驱动器的485通讯端子上。需要注意的是如果链路上有多台伺服每台的从站地址要设置成不同编号链路两端设备需要启用终端电阻。这一点我在后面的调试章节还会重点讲。2. Modbus-RTU帧结构解析先把协议啃透2.1 报文帧的基本组成Modbus-RTU一帧报文包含四个部分从站地址、功能码、数据区、CRC校验。看起来简单但每个字节在总线上的时序是有严格要求的。字段长度说明从站地址1字节0-2471-247可用0为广播地址功能码1字节03读寄存器、06写单个寄存器、10十六进制0x10写多个寄存器数据区N字节取决于功能码包含寄存器起始地址、数据长度、数据内容CRC校验2字节CRC16-Modbus低字节在前帧与帧之间必须有至少3.5个字符时间的空闲间隔。以9600波特率为例一个字符大约1ms3.5个字符就是3.5ms左右。如果两帧之间的间隔太短接收方可能把两帧数据当成一帧处理导致解析错乱。做PLC通讯程序时如果调用通讯指令的频率过高反而可能触发这个问题。2.2 三种核心功能码03、06、10本次实战用到三个功能码分别是读寄存器、写单个寄存器、写多个寄存器030x03读保持寄存器用于读取伺服的状态字、实际位置、实际速度等。报文格式是“从站地址03起始地址高字节起始地址低字节寄存器数量高字节寄存器数量低字节CRC”。060x06写单个寄存器用于写控制字、模式切换等单字操作。报文格式是“从站地址06寄存器地址数据CRC”。100x10写多个寄存器用于写目标位置、目标速度这类32位数据。因为一个寄存器只有16位32位数据需要占用两个连续寄存器这时候必须用0x10功能码一次写入两个字。举个例子读取1号从站、寄存器地址0x0B01、长度为1个字报文就是01 03 0B 01 00 01 CRC_LO CRC_HI其中0B01就是要读取的寄存器地址0001表示读取1个寄存器。对应汇川伺服的H0B-01对象字典也就是状态字。2.3 CRC校验的原理与手算方法CRC校验是Modbus-RTU最容易让新手迷糊的地方。如果你用串口调试助手手动发帧不把CRC算对伺服绝对不搭理你。CRC16-Modbus的算法核心是初始值0xFFFF多项式0xA001逐字节处理。我习惯在电脑上用Python脚本算CRC函数就这么几行def crc16_modbus(data: bytes) - int: crc 0xFFFF for byte in data: crc ^ byte for _ in range(8): if crc 1: crc (crc 1) ^ 0xA001 else: crc 1 return crc举例要发送01 03 0B 01 00 01这6个字节先把这6个字节传入函数得到CRC值然后将CRC的低字节放在帧尾倒数第二位高字节放在最后一位。也就是很多文档里写的“低字节在前”。当时我刚开始做串口调试时就栽在这个字节序上把高低字节写反伺服一直无响应排查了半天才发现是CRC字节序问题。2.4 用串口调试工具先验证一帧拿到驱动器后我强烈建议先用USB转RS485工具连接伺服配合串口调试助手手动发送一帧读取状态字的报文确认伺服能正常回复。这一步能帮你把“伺服通讯问题”和“PLC通讯问题”分开极大缩小排查范围。我的调试流程是这样的打开串口调试助手设置串口号、波特率9600、数据位8、偶校验、停止位1然后手动发送01 03 0B 01 00 01 CRC_LO CRC_HI如果一切正常会收到类似01 03 02 00 06 CRC_LO CRC_HI其中01是从站地址03是功能码02表示后面有2个字节数据00 06就是状态字的内容。看到这个响应说明驱动器通讯通道完全正常接下来再去折腾PLC程序思路就清晰很多。3. 汇川伺服侧参数设置让驱动器开口说话3.1 通讯参数组H0C的设置汇川伺服驱动器的参数通过前面板或调试软件InoDriverShop修改。Modbus-RTU通讯需要设置H0C组的几个参数我用表格整理了一份常用配置。参数含义常用设置说明H0C-00从站通讯地址1范围1-127多台伺服必须不同H0C-01通讯波特率596000-9对应不同波特率具体查阅手册H0C-02数据格式18E18个数据位偶校验1个停止位H0C-03通讯协议选择Modbus-RTU部分固件版本还需要设置协议类型H0C-05485终端电阻按需链路终端设备设为1中间设备设为0H0C-06通讯超时时间100ms主站超时后驱动器报警这里最需要注意的是H0C组参数修改后部分参数需要驱动器重新上电才能生效。我遇到过好几次现场改完参数直接发报文驱动器不响应结果发现是参数没真正加载。一般操作是修改后保存参数然后断电报文再重新上电。3.2 控制模式与指令来源的确认要让伺服通过Modbus-RTU接收位置指令光配好通讯参数还不够还得把驱动器的控制模式和指令来源切到Modbus通讯。汇川IS620N中一般用H02组参数设置控制模式位置控制、速度控制还是转矩控制。点位运动用位置控制模式也就是H02-01设为位置控制。关键是指令来源。默认情况下驱动器可能从脉冲端子接收指令必须把位置指令来源修改为Modbus通讯。具体是H02-03还是H0D组不同固件版本略有差异我建议直接以随机附带手册的“运行指令来源”章节为准。设置完同样要保存并重新上电。3.3 对象字典H0B组PLC眼中的伺服寄存器汇川IS620N将Servo对象字典映射到了Modbus保持寄存器区以H0B组为主。下面这张表是本次实战最核心的寄存器映射建议截图保存。Modbus寄存器地址对象字典含义读写属性0x0B00H0B-00控制字读写0x0B01H0B-01状态字只读0x0B02H0B-02目标位置32位读写0x0B03H0B-03实际位置32位只读0x0B04H0B-04目标速度32位读写0x0B05H0B-05实际速度32位只读0x0B06H0B-06目标转矩只读0x0B07H0B-07实际转矩只读注意32位的数据比如目标位置在Modbus里占两个字默认高位字在前、低位字在后也就是大端模式。在PLC侧组装数据时一定要先放高16位再放低16位。我见过不少同行把高低字颠倒结果伺服走的位置完全不是预想值。3.4 默认编码器线数是262144这个数值能改吗这是很多汇川伺服用户都问过的问题。MS1H4系列电机配绝对值编码器默认分辨率是262144线也就是电机转一圈编码器反馈262144个脉冲。那这个“262144”到底能不能改我的答案很明确编码器本身的分辨率是硬件特性不能通过参数修改。出厂后的262144就固定在编码器内部改不了也不需要改。但为什么有人觉得它能改因为在伺服驱动器的参数里确实提供了编码器分频输出比如H05组的脉冲输出分频和电子齿轮比电子齿轮分子/分母等参数。这些参数修改的是驱动器对外输出的脉冲数或指令换算关系不会改变编码器内部的实际分辨率。举个例子你可以设置电子齿轮比让PLC每发1000个脉冲电机转一圈但电机内部编码器反馈的仍是262144线分辨率精度并没有降低。所以当你看到驱动器里显示262144时不要去纠结怎么把它改小。你真正需要操心的是电子齿轮比的计算让PLC发的用户单位符合你想要的脉冲当量。3.5 电子齿轮比的计算示例电子齿轮比解决的是“PLC发的用户单位”和“电机实际转多少圈”之间的换算。假设现场要求PLC发送10000个单位电机刚好转一圈。而伺服内部一个单位对应多少编码器反馈呢这就要算电子齿轮比了。以编码器分辨率262144线为例如果一份位置指令对应1个编码器计数那么要让10000份指令转一圈电子齿轮比应该设置为262144:10000简化后约等于26.2144:1。但这样不是整数很多驱动器的电子齿轮比要求整数设定没法直接写。实际工程中我们会调整用户单位比如让每份指令对应0.001mm丝杠导程10mm电机转一圈走10mm那转一圈需要10000个用户单位此时电子齿轮比同样是262144:10000。如果比例不是整数就换用户单位比如改成每份指令对应0.01mm转一圈只要1000份指令齿轮比就是262144:1000依然不是整数。所以很多时候需要配合机械传动比一起调这就是另一个话题了。总之记住一点编码器线数是固定的你需要调的是电子齿轮比分母和分子。4. 西门子PLC侧配置从零到能跑4.1 硬件接线RS485 A/B与屏蔽处理RS485接线看着简单其实是故障高发区。CM1241 RS485模块上的A、B端子对应汇川伺服驱动器的485通讯端子。接线时用屏蔽双绞线A接A、B接B然后屏蔽层单端接地一般在PLC侧接地。很多人图省事不接地线等到现场变频器一启动通讯就开始乱码那时候后悔就晚了。如果链路上只有PLC和伺服两台设备且CM1241和伺服分布在链路两端那两端的终端电阻都要启用。CM1241模块侧面有终端电阻拨码开关伺服侧通过H0C-05参数启用。如果链路中间还有其他设备中间设备的终端电阻必须关闭。4.2 TIA Portal中组态CM1241 RS485在TIA Portal博途中先添加S7-1200 CPU再添加CM1241 RS485模块。组态时可以看到模块的硬件标识符比如“64”之类的数字这个标识符在后面的通讯指令里要作为PORT参数使用。通讯口的波特率、校验方式等在硬件组态里可以先随便设真正生效的是后面程序里MB_COMM_LOAD指令设置的参数。这一点很多初次接触的朋友会被绕晕觉得“我硬件组态里明明设了9600怎么程序里还要设一遍”。记住CM1241的串口参数最终以MB_COMM_LOAD的形参为准。4.3 初始化指令MB_COMM_LOAD在OB1里调用MB_COMM_LOAD指令负责初始化串口通讯参数。核心形参如下形参设置值说明PORTCM1241硬件标识符在PLC变量的系统常量中查找BAUD9600与伺服H0C-01一致PARITY2偶校验与伺服H0C-02一致DATABITS88个数据位STOPBITS11个停止位MB_DB分配一个全局DB用于存放通讯控制数据MB_COMM_LOAD的REQ端用首次扫描脉冲触发一次即可不需要每个扫描周期都去初始化。DONE和ERROR引脚可以接到M点或DB里方便在线监控。4.4 主站读写指令MB_MASTER初始化完成后用MB_MASTER进行单次读写。MB_MASTER是边沿触发的每次REQ从0变1时发送一次请求。核心形参如下形参说明REQ上升沿触发通讯请求RW0表示读1表示写ADDR从站地址功能码起始地址组合值DATA_PTR指向存储数据区的指针LEN数据长度读写字的个数重点是ADDR的拼接。S7-1200的MB_MASTER要求把从站地址、功能码、起始地址打包成一个双字。比如读1号从站、功能码03、起始地址0x0B01ADDR就等于16#01030B01其中01是从站地址03是功能码0B01是寄存器地址。如果是写控制字功能码换成06ADDR就是16#01060B00写多个寄存器时功能码用160x10比如写目标位置0x0B02ADDR为16#01100B02这个ADDR格式我在现场给不少同事讲过大家最容易错的就是把从站地址和功能码的位置搞混。一定记住高字节是从站地址次高字节是功能码低两个字节是寄存器地址。4.5 点位运动控制的程序逻辑我写一个最简单的点位控制流程大家可以直接参考首次扫描调用MB_COMM_LOAD完成初始化。用MB_MASTER写控制字0x0B00值为1使能伺服。延时一段时间确认状态字0x0B01的bit0为1表示伺服已使能。用MB_MASTER功能码0x10写目标位置寄存器0x0B02连续写两个字数据先放高字再加低字。再次用MB_MASTER功能码06写控制字值为3触发运行。周期读取状态字和实际位置判断运动是否完成。LEN参数注意读写单个寄存器16位数据时LEN1读写32位数据比如目标位置时LEN2。DATA_PTR指向的数据区如果是32位数据需要保证两个字连续存放。我在实际项目中会把每次MB_MASTER的ERROR引脚接到一个故障DB一旦状态字不是0就把状态值记录下来。这样即使伺服或者通讯出问题也能快速定位是哪个请求失败。5. 常见问题与排查技巧实录5.1 通讯超时故障速查表调试中通讯超时是最常见的问题我把这些年踩过的坑整理成一张表按出现频率排序。现象可能原因排查方法主站报16#8180从站无响应伺服地址、波特率、数据格式不一致用串口调试助手直接发帧测试伺服是否回复主站报16#8180从站无响应RS485 A/B接反对调A/B线主站报16#8180从站无响应伺服未上电或通讯参数修改后未重启断电重启驱动器偶发超时缺终端电阻、线缆过长、屏蔽层未接地检查链路终端电阻和接地偶发超时波特率过高导致抗干扰能力下降降到9600试一下通讯正常但数据错乱校验位、停止位设置不一致PLC和伺服统一为8E1或8N1伺服能通讯但不动作控制模式或指令来源未设置为Modbus检查H02组控制模式和指令来源5.2 西门子16#8180错误代码详解16#8180这个错误在S7-1200 Modbus-RTU通讯里最常见。西门子官方文档的解释是“从站无响应”或“请求超时”。说白了MB_MASTER把请求帧发出去但在设定的超时时间内没收到从站回复于是报这个错。排查思路很简单先把PLC放在一边用USB转RS485和串口调试助手手动发一帧读状态字的报文。如果伺服也不回复问题一定出在伺服侧或接线侧。如果串口助手能收到回复那问题就回到PLC侧——重点查MB_COMM_LOAD的参数是否和伺服一致ADDR的地址拼接是否正确以及RS485模块接线。这里还有个容易被忽略的点MB_MASTER的LEN参数如果设错也可能导致通讯失败。比如写目标位置时LEN设为1而实际需要2个字PLC只发了一个字伺服端解析就会异常导致不回复或回异常码。5.3 数据字节序与单位换算问题数据错乱是另一个高频问题。Modbus协议规定多字节数据大端传输也就是高字节在前。但伺服驱动器的实际表现偶尔会和手册有出入我的建议是写一个固定值去验证。比如把目标位置寄存器写成0x0001C350十进制115536然后用伺服面板或调试软件看实际位置值。如果显示115536说明字序正确如果显示的是其他值大概率是高低字颠倒调整一下PLC里数据的存放顺序即可。还有个经验PLC的DATA_PTR如果指向的是Byte数组或Word数组要注意数据对齐。S7-1200里指针访问的数据区最好用位存储器M区或者DB的绝对地址避免优化访问带来的麻烦。5.4 实测下来的几条独家心得最后分享几条现场总结出来的经验都是常规手册里不会写的内容。第一调试时先用串口助手把伺服通讯打通再动PLC程序。这样做的好处是能把问题分成“伺服侧”和“PLC侧”两段每段单独验证效率最高。我有一次直接上PLC折腾了两小时没搞定结果用串口助手十分钟就发现是CM1241模块的DB数据区地址写错了。第二使能之前一定要确认状态字的反馈。很多伺服必须先看到使能位反馈有效才会响应运行指令。PLC里别省那几个扫描周期写完控制字加一个延时或者轮询状态字确认到位后再发下一帧稳定性会好很多。第三参数修改后记得保存并断电重启。我见过不少现场参数在InoDriverShop里改了也保存了但驱动器没重启导致新参数没生效。通讯类参数尤其敏感不重启很容易出现“改了半天没变化”的怪象。第四通讯超时时间不要设太短。MB_MASTER的超时设置如果太小在恶劣电磁环境下容易误报但也不要太长否则故障响应太慢。我一般设置在100-300ms之间兼顾稳定性和实时性。最后分享一点个人体会我做设备调试这些年越来越觉得通讯方案不是越高级越好。Modbus-RTU虽然“老”但在这种小规模点位控制场景里稳定、直观、好排查反而是最省心的选择。汇川伺服加西门子PLC的组合在市场上保有量巨大两个设备之间的Modbus-RTU通讯值得每个自动化工程师认真掌握。按照我的习惯每次新项目会先做一张通讯参数速查卡把伺服H0C组参数、H0B组关键寄存器地址、PLC侧MB_COMM_LOAD和MB_MASTER的配置全部写在一张纸上。现场调试时对照这张纸操作基本能一次通过。这篇文章就算是一个公开版的速查卡希望对大家有用。