1. 为什么一上来就让人栽跟头的往往是“从哪里开始配”先说个我自己的经历。第一次拿FX5U做ModbusTCP主从站通讯我以为把GX Works3打开、拖几个指令就完事了结果整整折腾了一个下午PLC侧报错、触摸屏读不到数据、调试助手那边连握手都过不去。最后发现问题出在一个特别基础但又特别容易被忽略的地方——以太网端口参数里的“对象服务”配置以及ModbusTCP报文里从站地址Unit ID没对上。这两个点几乎涵盖了新手第一次上手ModbusTCP时会踩到的80%的坑。在看这篇文章前建议你先明确一件事FX5U的ModbusTCP通讯CPU模块自带以太网口本身就支持不需要额外加功能模块或专用通讯板。主站、从站都能做。主站就是用指令去读写别人的数据从站就是把自己的数据区开放给别人读写。这篇文章我会把完整链路拆开讲从GX Works3的项目参数开始到ModbusTCP指令的调用再到数据映射和排错思路全程基于FX5U一台PC模拟从站也可以用另一台FX5U、或者第三方设备的实测经历。适合谁看三种人。第一种手头有FX5U项目、想快速打通ModbusTCP但不想翻手册的第二种做产线设备联调需要PLC和伺服、变频器、仪表、视觉系统做TCP通讯的工程师第三种之前只玩过串口ModbusRTU第一次转到ModbusTCP对端口、Unit ID、字节序、以太网帧结构这些概念还没有形成清晰认识的。这篇文章就是为你准备的。2. ModbusTCP和ModbusRTU的本质差异先理解这套“寄信规则”很多人上来就问“为什么我的TCP报文跟RTU报文长得不一样”。其实从通讯模型上看ModbusTCP就是Modbus协议族里跑在以太网TCP/IP之上的一种变体。它和RTU最大的区别在于报文容器变了但内部业务逻辑没变。用寄信来类比。ModbusRTU是写信信封和信纸是一体的一封完整的信包含地址、功能码、数据、校验一个字节都不能多、不能少必须严格按时间顺序读完。而ModbusTCP是先把信装到一个“TCP信封”里信封上有自己的头MBAP头共7个字节然后把原来RTU里的功能码和数据原封不动塞进去。最直观的变化就是RTU里那个用来区分不同从站的8位站号在TCP里变成了Unit ID放在MBAP头的最后一个字节。这里有一个关键认知ModbusTCP标准里一个IP地址下的Unit ID通常只是逻辑上的区分很多设备如某些网关、模块可能只支持Unit ID1或者Unit ID255。但FX5U作为从站时Unit ID是可以任意指定的0-255只要你在从站配置里填的值和主站报文里发的值一致即可。这一点极其重要因为FX5U不像某些专用Modbus网关那样固定Unit ID为255也不会自动忽略Unit ID——它严格遵守报文里的Unit ID对不上就返回异常码或干脆不响应。另一个很多人忽略的差异是端口号。ModbusTCP默认端口是502这是IANA分配给ModbusTCP的标准端口。如果你在FX5U侧配置的是502而调试软件或第三方设备默认也是502那没问题但如果某个设备固件里默认端口是503、504甚至自定义端口两边就必须手动对齐。实测中我就遇到过一台老款仪表默认用1502端口结果PLC侧怎么配都通不了折腾了好久才在仪表菜单里翻到端口设置。字节序问题也要提前有个概念。Modbus协议本身规定多字节数据是大端高字节在前但FX5U内部的寄存器数据在GX Works3的监视窗口里是按字显示如果你从主站读到的是两个连续的保持寄存器你看到的高16位和低16位分别对应哪个地址完全取决于你程序里的拼接顺序。这个问题在后面的“数据读写”部分我会专门展开。表格对比一下两者最核心的差异对比项Modbus RTUModbusTCP传输载体串口RS232/RS485以太网/TCP/IP从站寻址8位站号1-247IP地址 Unit ID报文头无独立头靠时间间隔切分MBAP头事务ID协议ID长度Unit ID校验CRC16必须计算无CRC由TCP可靠性保证默认端口无取决于串口参数502最大数据量受报文长度限制一般125个字以内理论上可更大但受实现限制FX5U同样建议125字封顶理解了这张表你就知道为什么很多人从RTU转TCP时会困惑“为什么没有CRC了”因为TCP协议本身已经保证数据不丢包、不错序、到达完整性ModbusTCP不再需要底层校验。省掉CRC之后报文结构确实干净了不少。3. 主站配置GX Works3里最容易漏掉的那个勾选框3.1 先给PLC一个正确的“网络身份”FX5U做主站本质是PLC主动发起TCP连接然后发送ModbusTCP请求。所以在GX Works3里第一步不是写程序而是把以太网口参数和“对象服务”配置弄对。新建项目机型选FX5U我这里用FX5U-32MT/ES为例。左侧导航找到“参数 → FX5UCPU → 模块参数 → 以太网口”。在这里你需要设置IP地址比如192.168.1.10子网掩码255.255.255.0默认网关如果你只是在同一局域网内通讯可以留空或者填路由器地址不影响PLC和其它设备的直连保存后有个位置是很多人看不到但必须勾上的地方“以太网端口配置”里的“ModbusTCP通信”选项在GX Works3的某些版本里它藏在模块参数的“对象服务”区域名字类似“MODBUS/TCP Connection”或“MODBUS/TCP通信”。如果你没有勾选这一项程序里即使写了ModbusTCP指令CPU也会在运行时报错错误代码一般在SD寄存器里能看到。这里必须暂停一下说一个非常容易混淆的点FX5U的固件版本和GX Works3的版本不同菜单路径叫法会有差异。以我用的GX Works3 1.100L和FX5U固件1.180为例路径是模块参数 → 以太网口 → 对象服务 → 内置以太网端口通信支持设置 → MODBUS/TCP通信。老一点的固件里可能不叫“对象服务”而是直接叫“通信协议支持功能”或“内置以太网端口”。总之你找的关键词是“MODBUS”和“TCP”找到了就勾上。3.2 主站指令SP.SOCOPEN、SP.SOCWRITE、SP.SOCREAD还是MBR/MBW这一节可能是大家最懵的地方。FX5U的ModbusTCP主站功能GX Works3里其实提供了两套方案方案A使用通用Socket通讯指令SP.SOCOPEN、SP.SOCWRITE、SP.SOCREAD这是FX5U最底层、最灵活的方案。你需要自己按ModbusTCP协议格式打包报文填事务ID、协议ID、长度、Unit ID、功能码、寄存器地址、数据然后通过SP.SOCWRITE发给对方再通过SP.SOCREAD收响应。优点是完全可控任何支持ModbusTCP的设备都能通讯缺点是报文需要自己拼工作量不小而且出错排查成本高。方案B使用专用ModbusTCP指令MBR/MBW或者旧固件里的MBR/MBW指令名可能不同GX Works3为FX5U准备了类似“MBR”Modbus Read和“MBW”Modbus Write的专用指令只不过在FX5U里这两个指令实际上是作为“扩展指令”出现的需要你在指令列表里找到“Modbus TCP”相关的指令直接在梯形图里拖出来使用。指令内部自动组装MBAP头、功能码和寄存器地址你要做的就是指定从站IP、端口、Unit ID、寄存器地址、数据长度、存储软元件等参数。我的建议如果是第一次做FX5U的ModbusTCP直接选方案B。理由很实际——专为FX5U设计的ModbusTCP指令封装度已经足够高参数清晰成功率远大于手拼报文。方案A适合那种你明确知道对方设备不按标准ModbusTCP走、需要自己定制报文头的场景比如某些国产仪表、定制网关、或者需要同时读写多个功能码的场景。我实测下来方案B的梯形图大致如下结构[ MBW 请求 ] - 执行条件常开触点比如M100 - 从站IPD200D2034个字存放IP地址 - 端口D204存放端口号比如502 - Unit IDD205 - 起始寄存器地址D206 - 写入数据长度/数据D210开始的连续字具体每个参数的软元件编排不同固件版本略有差异但核心思路不变你要把“IP地址、端口、Unit ID、功能码类别、寄存器起始地址、数据长度”这几项准确地告诉指令。以MBW为例比如要把D100里的16位数据写入从站的保持寄存器40001你可设置起始寄存器地址0数据长度1数据源D100。如果你要写32位数据就必须把D100和D101两个连续字都作为数据源而且要注意高低字顺序。提示GX Works3里这些ModbusTCP专用指令在“指令”窗口搜索“MBR”或“MBW”即可如果找不到确认你已勾选ModbusTCP通信支持功能。没有勾选对象服务指令列表里出不来的情况我遇到过两次。3.3 主站实操从建立连接池到轮询读写主站下发请求最忌讳的是“每扫描周期都发一次”。ModbusTCP主站一般应采用轮询式结构先建立连接再依次执行读、写操作中间留出响应超时时间一轮结束后延时几十毫秒再开始下一轮。我先给出一个实用的轮询思路基于方案B用一个字作为状态机比如M0表示“空闲”、M1表示“读请求发送”、M2表示“读响应已接收”、M3表示“写请求发送”、M4表示“写响应已接收”。上电后先触发连接建立确认连接成功后M0置ON。在M0 ON时触发读请求MBR执行完成后根据完成标志跳转到M1或故障分支。读完成后触发写请求MBW完成后回到M0并延时。这样做的原因是TCP通讯是“请求-响应”模型一次请求没收到响应之前你不能发下一条。你用状态机串行化以后才不会出现“PLC同时发了两条请求把从站搞糊涂”的情况。我在现场调试时多次用这个模式稳定性很好连续跑数天不掉线。关于超时时间FX5U的ModbusTCP指令一般有可以设定的“监视时间”单位通常是秒或毫秒视具体指令而定。我习惯设置为500ms到1s。太短的话网络抖动或者从站响应慢一点就误报超时太长的话故障响应太慢设备的急停信号可能都处理不过来。如果你的从站是伺服驱动器或变频器响应时间通常在几毫秒到几十毫秒500ms绰绰有余如果是智能仪表、视觉相机这些响应较慢的设备建议设为1s以上。4. 从站配置把FX5U变成一个“TCP服务器”4.1 开启ModbusTCP从站功能的参数位置FX5U作为ModbusTCP从站时逻辑是“别人来连我”PLC不需要主动连谁。在GX Works3里的配置路径依然在以太网口的对象服务设置中。找到“MODBUS/TCP通信”相关的选项后把它设为“作为从站使用”然后配置一个或多个“服务端口”监听端口默认是502。还需要注意“连接数”或者说“并发连接数”的设置。默认可能只允许1个连接如果你同时有触摸屏、上位机、调试助手等多个客户端想连PLC就必须把这个数值调大。我拿FX5U做过实测同时开3个客户端去读PLC数据没压力但连接数设置很隐蔽藏在以太网端口的“连接配置”表格里需要你手动去“追加”连接指定连接协议为“ModbusTCP Server/MODBUS”并且给这个连接分配一个固定端口。4.2 从站数据区映射我要开放哪些寄存器给别人读这是从站配置里最核心、也最容易绕晕的部分。ModbusTCP里四种对象线圈Coil功能码01/05/15、离散输入Discrete Input功能码02、输入寄存器Input Register功能码04、保持寄存器Holding Register功能码03/06/16。对于FX5U来说它的CPU软元件不能直接被Modbus报文读写需要通过**“Modbus从站缓冲存储器”或“软元件映射”**来中转。具体来说你在对象服务的ModbusTCP从站设置里会看到一张类似“寄存器分配表”的东西允许你把Modbus地址映射到FX5U软元件比如Modbus地址十六进制功能FX5U软元件映射0x0000 - 0x03FF保持寄存器40001-40128等D0-D开始0x0000 - 0x01FF线圈00001-等M0-M开始但这里有个坑不同固件版本提供的映射能力不同。有的旧固件里你只能通过**“串行通信模块/以太网端口用Modbus从站功能”**自动把保持寄存器映射到D区或者把线圈映射到M区映射范围固定比如保持寄存器1024个点线圈1024个点。我建议你在配置界面上重点确认三件事映射的起始软元件地址是多少是不是D0映射的寄存器数量上限是多少线圈、保持寄存器分别支持的功能码是否完整比如是否支持05写单个线圈、15写多个线圈、06写单个寄存器、16写多个寄存器实测时常用的是保持寄存器映射到D区。我要强调一点Modbus地址和软元件地址不是一回事你必须在脑子里做大端/小端、高位/低位的转换。例如集团公司要求上位机通过Modbus读PLC的D100和D101两个字组成的一个32位浮点数。上位机一般会按“第一个寄存器是高16位还是低16位”来拼。如果PLC侧把D100放低16位、D101放高16位而上位机恰好反着拼最终结果就是一个特别离谱的数值。这个问题不是你的配置错了而是“字节序约定不一致”。我的建议是在主站和从站两端都按“D100为高16位D101为低16位”或“D100为低16位D101为高16位”统一约定并在项目注释里标明。若要省心上位机开发时尽量按Modbus标准大端处理PLC侧按大端地址排列写入数据这样两边不用做额外转换。4.3 用PC模拟一个ModbusTCP从站来联调做主站调试时最痛苦的是“没有对端设备”。一个非常实用的做法是用ModbusPoll这类PC软件来模拟从站或者如果你是要测试“FX5U从站”那就用ModbusPoll的“从站模式”反向连接。这里我以PC模拟从站为例说明怎么验证FX5U主站PC和FX5U接在同一个交换机上或者网线直连。PC网卡IP设为192.168.1.20FX5U设为192.168.1.10。打开ModbusPoll免费版即可选择“Slave Mode”监听端口502Unit ID设为1。在GX Works3里把MBR/MBW指令的从站IP设为192.168.1.20、端口502、Unit ID 1。把PLC切到RUN触发M100执行主站轮询观察ModbusPoll界面里的寄存器数值是否被写入或读取。我第一次用这个方式联调时只花了20分钟就确认了所有参数配置正确。但这里有一个容易忽略的点PC上如果有别的程序占用了502端口从站模拟器会启动失败。常见的是SQL Server Reporting Services、某些数据库服务、或者其它工控软件会占用502。Windows下打开命令行执行netstat -ano | findstr :502就能看到是谁占用了。如果你用ModbusPoll模拟从站那么PLC作为主站发的报文、读写的数据你都能在ModbusPoll的“Communication Traffic”窗口里看到报文明细。这是排查问题最有力的工具我在后面排错部分会详细讲。5. 数据读写实战从D区到上位机的完整链路5.1 主站读保持寄存器MBR使用示范假设现场需求是FX5U主站读取一台带ModbusTCP接口的温控器温度值存放在保持寄存器地址0x0064对应Modbus地址400101即偏移100里共2个字组成32位数据。设置从站IP192.168.1.50温控器IP端口502Unit ID1功能码03读保持寄存器起始寄存器100数据长度2存储起始软元件D100第1个字、D101第2个字执行完后PLC的D100和D101就是温度值的高16位和低16位。这里需判断温控器的字节序。如果温控器手册说“高字节在前”则D100是高16位即温度值 (D100 16) D101如果手册说“低字节在前”那可能是温度值 (D101 16) D100用梯形图或ST语言都能算但别在梯形图里硬写移位指令太繁琐。推荐直接用ST或结构化文本写一个转换功能块。FX5U支持在梯形图里嵌入ST程序计算变干净很多。如果温度值是IEEE 754浮点数则要先把D100、D101组合成32位再用“DINT_TO_REAL”之类的指令或者调用浮点数转换函数。FX5U的GX Works3里有标准库函数可以直接把32位数据按IEEE754解释为REAL。5.2 主站写保持寄存器MBW使用示范再假设你不仅读温度还要往下发一个设定值目标寄存器地址0x0065偏移101数据类型是16位无符号整数值放在PLC的D200里。设置从站IP192.168.1.50端口502Unit ID1功能码06写单个保持寄存器或16写多个保持寄存器起始寄存器101数据源软元件D200数据长度1如果你要连续写多个字比如设定温度、设定湿度起始寄存器指向首个地址数据源软元件指向连续的首个D数据长度设成N即可。这里我想特别提醒一点功能码06只能写一个寄存器功能码16可以写多个寄存器。MBW指令会根据你指定的数据长度自动选择功能码。但有些老设备只支持06不支持16这时候即便你只写一个寄存器把数据长度设成1你的MBW指令有可能仍然使用功能码16具体看FX5U固件实现那老设备就返回异常码。遇到这种设备你需要查阅FX5U该指令是否提供“功能码强制指定”的参数。如果没有建议改用方案ASocket指令手拼报文来发送功能码06。5.3 32位数据和浮点数的字节序拆解这是数据读写里真正体现功力的地方。很多工程师配好了通讯、且监控窗口里能看到数据在变但算出来就是个天文数字十有八九是字节序问题。我举个具体例子某伺服驱动器的实际速度值是32位有符号整数存在保持寄存器地址0x0300-0x0301。手册明确先存储高16位再存储低16位也就是寄存器地址0x0300是高字0x0301是低字。那你在FX5U主站的MBR指令里起始寄存器填0x0300长度2存储到D300、D301那么D300是高字、D301是低字则实际值(32位) (D300 16) OR D301但如果手册写的是“寄存器地址小的存低字”小端序则实际值(32位) (D301 16) OR D300这是纯粹的地狱级细节没有工具能帮你自动判断只能靠设备手册和现场验证。验证方法也很原始让设备动起来看速度值正负是否符合逻辑。比如伺服正转时速度应为正如果你算出来是负数或者跳变极大那基本就是字节序反了。对于浮点IEEE754二进制表示是高字在前还是低字在前不同设备也不一样。标准Modbus协议没规定浮点字节序完全看实现。很多国产设备默认低字在前而西门子、三菱的很多协议库默认高字在前。因此在写上位机程序时必须做成可配置项高低字交换 高低字节交换。在FX5U里也一样最好封装一个“Swap功能块”。6. 排错实战抓包 状态寄存器 指令返回值的组合拳6.1 连不通先看错误代码FX5U的ModbusTCP指令在完成时通常有“异常输出”和“状态”相关软元件。如果是MBR/MBW可能会有“执行中”“正常完成”“异常完成”三个标志以及一个“异常代码”字。当异常完成时不要急着改参数先把异常代码记下来。这些代码的对应表在GX Works3的指令帮助里能查到常见的有异常代码/状态含义常见原因连接超时无响应IP不对、端口不通、从站未监听502请求被拒绝从站返回Modbus异常码寄存器地址超限、功能码不支持事务ID不匹配响应和请求对不上重发逻辑没做好或从站实现有bug本地端口冲突无法发起连接端口被占用、连接数耗尽有一次我配置了一台FX5U读取第三方网关网关始终返回异常码2。异常码2的意思是“非法数据地址”。我开始以为地址配错了反复核对地址没问题。最后抓包发现MBR把寄存器地址解释错了因为我把“寄存器编号”直接填成了Modbus地址比如填40001而指令期望的是“地址偏移”0-65535。把40001改成0对应40001的偏移后通讯秒通。这是个非常典型的“地址语义不统一”的坑。6.2 用Wireshark抓包让问题无法遁形如果你身边没有ModbusPoll这类模拟器也可以直接从PC上用Wireshark抓包观察ModbusTCP报文。先用网线把FX5U和PC接到交换机然后设置端口镜像或者简单点直接在PC上运行Wireshark抓所有流量筛选条件填modbus或tcp.port 502就能看到PLC发出的请求报文。抓包能有效解决以下这类问题报文是不是真的发出去了如果没发检查程序逻辑和指令执行条件。请求中的Unit ID、寄存器地址、功能码是不是符合预期不符合就查参数配置。从站有没有响应如果没有响应查从站侧IP、端口、监听状态。响应里是不是带异常码带上异常码就能直接定位到从站侧问题。我给自己的排查顺序永远是先看报文再看参数。因为报文是事实参数可能因为版本差异、菜单名称不同而让你产生误解。6.3 现场最常见的五大典型故障及对症解法我在几个项目里反复遇到以下五类问题写成清单供参考现象PLC侧MBR/MBW一直“执行中”无完成标志。原因TCP连接根本没建立成功。排查从站IP、端口、防火墙、服务是否启动。用“ping 通不通”作为第一步然后用telnet IP 502测试端口通不通Windows下需要先开启Telnet客户端。实测中很多工控设备装了防火墙或安全软件会拦截502端口入站连接。现象连接可以建立但读不到数据或读到0。原因寄存器的地址偏移和功能码不匹配。确认是否把起始地址填成了“40001”这种绝对地址而指令需要的是“0”这种相对地址确认从站数据区是否有数据、地址是否有越界。现象通讯正常但数值是乱的。原因字节序、字序不一致。优先查D区高低字的组合方式其次查IEEE754浮点数的字序。这种问题最“坑”有时需要把32位拆成两个16位分别监视观察高字和低字的值是否符合预期。现象PLC重启或网络闪断后不能自动恢复通讯。原因TCP连接没有自动重连机制。FX5U的ModbusTCP指令在连接断开后不会自动重连需要你编写重连逻辑通常的做法是检测断线标志、延时、重新触发连接指令。我见过有同行没有做重连逻辑导致只要交换机重启一次产线就得断电重启PLC才能恢复。现象多个从站设备、或者触摸屏和上位机同时连FX5U从站某一路连不上。原因连接数被占满或者连接配置里没有开放足够多的连接。去以太网口“连接配置”里追加连接把协议设为ModbusTCP Server并指定端口和允许的连接数。6.4 一个完整的排错链路从连不通到彻底打通用一个实际案例带你走一遍排查链路。场景FX5UIP 192.168.1.10读取一台变频器IP 192.168.1.88的运行频率频率放在保持寄存器0x0002。第一步PLC侧执行MBR观察到指令始终“执行中”。第二步用PC ping变频器IP通则继续不通则检查网线、交换机、IP网段。第三步PC用ModbusPoll做一个相同请求IP 192.168.1.88端口502Unit ID1功能码03起始地址2长度2如果ModbusPoll能读到数据说明变频器正常且通讯链路正常问题一定在PLC参数或程序侧如果ModbusPoll也超时说明问题在变频器侧或防火墙。第四步用Wireshark抓包发现PC发出的请求报文没有收到响应初步判断变频器端口或Unit ID不对。查阅变频器手册发现它默认Unit ID是255而不是1。改Unit ID后重新请求ModbusPoll正常读取。第五步回看PLC把MBR的Unit ID从1改成255重新执行数据正常。这套链路的关键点在于用第三方工具先验证“链路本身通不通”再把问题从“链路问题”和“PLC配置问题”两个方向切割。这样能省下大量时间。7. 进阶要点重连机制、多从站轮询和一致性锁定7.1 断线自动重连现场稳定性的生命线在真实产线上通讯中断是家常便饭交换机掉电、电缆松动、对端设备重启任何一次断网如果PLC不自动恢复都会造成停机。FX5U的ModbusTCP没有内置自动重连所以必须自己做。我的做法是用一个小状态机正常工作状态S0→ 发现通讯故障S1→ 延时3秒S2→ 尝试重连或重新触发请求S3→ 回到S0。发现通讯故障并不难指令的异常完成标志为ON即可。但要注意如果是“请求发出后无响应”不是连接一定断了可能只是对方忙。这种情况下不要立刻重连而是继续重发请求重发三次后仍失败再判定连接断开。连接断开后需要执行的步骤是先SP.SOCCLOSE如果方案B内部没有自动关闭可能需要你主动调用关闭指令再延时再重新发起连接。在共享端口场景下重连动作需要加互锁避免多个任务同时触发重连造成资源竞争。7.2 多从站轮询地址离散也要保持稳定节奏如果一台FX5U主站要带多个TCP从站比如3台伺服你会遇到一个问题不同从站的IP不同但都通过同一套轮询逻辑读写。这时我建议把每个从站的通讯参数都定义在一整片D区中用指针或间接寻址动态切换从站。例如D300-D303从站1的IPD304从站1的端口D305从站1的Unit IDD310-D313从站2的IPD314从站2的端口D315从站2的Unit ID程序里用变址寄存器Z或指针P来遍历每个从站的参数区。如果从站数量多最忌多条MBR/MBW同时触发一定要串行化。我在现场做过8台变频器的轮询周期设定为100ms左右完全没有问题。7.3 数据一致性读回校验和先读后写ModbusTCP本质是TCPTCP有可靠传输但应用层数据仍可能因为对端逻辑错误而产生错误数据。有些关键控制信号比如“启动”“急停”这些指令不能只发出一次就结束必须采用“发出后回读校验”的机制。具体做法可以是主站写完成功后紧接着发起一次相同地址的读操作把读回的值和写入的目标值比较。一致则认为写成功不一致则重发或报警。如果通讯对象是安全相关的设备建议在数据中加入类似序列号的字段每次写入递增一个值从站校验序列号是否更新以检测数据包是否被延迟重放。这在复杂的网络环境中很有用。此外写入的关键参数在从站侧也应有备份当通讯中断恢复后PLC应重新下发一次当前目标值而不是仅仅依赖从站掉电保存。因为很多设备的保持寄存器在断点后可能恢复成默认值如果你不及时刷新会出大问题。8. 我在几个真实项目里总结的“土办法”和经验值8.1 通讯参数的命名习惯让你的程序能维护我做项目时会在PLC数据块或者注释里把“IP地址、端口、Unit ID、寄存器起始地址、数据长度”用标签管理起来并在软元件注释里标注“这是谁的寄存器、什么数据类型、是什么物理量”。这么做半年以后自己翻程序才不会懵。举个例子软元件注释可以这样写软元件注释D300从站1 IP字节1D301从站1 IP字节2D302从站1 IP字节3D303从站1 IP字节4D304从站1端口号502D305从站1 Unit ID考虑到很多人做项目时赶工期注释能省则省但我强烈建议至少把多从站场景下的这些注释写上。ModbusTCP的参数组合太多了一旦忘了哪个是端口、哪个是Unit ID排查起来非常痛苦。8.2 用ModbusPoll“反向验证”FX5U从站我屡试不爽的惯例当FX5U做从站时我需要验证“PLC能不能被远程读”。我的做法是在GX Works3里把ModbusTCP从站映射配置好下载程序并RUN然后用ModbusPoll连接PLCIP填PLC的IP如192.168.1.10端口502Unit ID填配置的值然后读保持寄存器。如果ModbusPoll能正确读回D区的数值说明从站配置OK如果不能优先检查Unit ID、寄存器偏移和地址映射。这个“反向验证”的习惯可以帮你避免很多不必要的猜疑。比如当触摸屏读不到PLC数据时你先用ModbusPoll去读如果ModbusPoll能读到而触摸屏读不到那问题就锁定在触摸屏配置上了而不是PLC侧。8.3 关于端口502被占用、虚拟网卡、防火墙等环境问题在三菱GX Works3的开发环境里如果你同时装了VMware、VirtualBox这类虚拟化软件或者安装了某些工业网关客户端PC的502端口可能被占用导致你本地的Modbus从站模拟器没法启动。实测中我遇到过VMware的NAT服务悄悄占了502端口。排查方法netstat -ano | findstr :502 tasklist | findstr PID找到占用进程后关掉或者改ModbusPoll的监听端口比如改到1502。改端口后PLC侧的端口也要同步改。防火墙方面Windows的防火墙默认可能会拦截502端口的入站连接。如果你在PC上搭从站模拟器必须在防火墙入站规则里放行502端口或将网络配置文件设为“专用网络”后允许应用通过。这类环境问题虽然不高级但排查出来往往要花不少时间。9. 一些别人不会写进说明书、但能让效率翻倍的小细节最后分享几个纯粹是靠时间堆出来的经验。第一在GX Works3里用“标签”而非“绝对地址”来管理Modbus通讯参数。数据不直观的时候用注释和标签能少走很多弯路。而且标签在功能块封装和重复调用时非常有用。第二写功能块FB时尽量把通讯状态做成一个结构体。我的习惯是包含以下成员通讯使能、连接状态、请求状态、最后一次异常代码、累计故障次数、最后成功通讯时间。靠这套数据你在触摸屏或上位机上能直接展示“通讯是否健康”比单纯看一个BOOL“通讯正常”要可靠得多。第三协议调试阶段不要直接接到真实变频器或伺服上先用PC模拟器验证报文。这个我已经反复强调过但在现场仍然很多人图省事直接接设备一旦出问题你甚至不知道该怀疑PLC还是怀疑设备。用模拟器可以把变量限制在一个很小的范围内。第四长时间验证时要增加“心跳监控”机制。比如让从站每秒钟翻转一个特殊寄存器一个计数器主站通过读取这个计数器是否递增来判断通讯是否“活着”。相比超时判断这个方式能更快发现“连接还在但数据停滞”的隐形故障。老实说ModbusTCP本身不是一个复杂的协议但因为它跑在工业以太网上牵扯到IP、端口、防火墙、连接管理、字节序、设备兼容性综合起来的坑一点也不比那些高大上的总线少。我在第一次成功跑通FX5U主从站通讯时最大的感慨是“原来只要把Unit ID统一、端口统一、寄存器偏移语义统一事情就成了大半。”这几条到今天依然是我判断一个ModbusTCP项目能否顺利交付的第一标准。如果你接下来的项目涉及FX5U配合变频器、伺服、仪表或上位机做ModbusTCP通讯建议你从这篇里的主站配置、从站地址映射、报文字节序三个部分入手先把最小系统打通再考虑多设备轮询和断线重连。这样一步一步来现场出问题的概率会低很多。