
1. 两套体系碰在一起通信这件事到底难在哪做过产线改造的人大概率都遇到过这种局面车间里原本跑着一套西门子S7-1200的控制柜后来因为工艺扩展或者设备整合又进来一台三菱Q系列PLC两边各自管着一摊设备数据却需要互通。可能是S7-1200要把配方参数下发给Q系列也可能是Q系列要把采集到的工位状态回传给S7-1200做集中显示。这时候问题就来了——两个品牌、两套编程软件、两种数据格式怎么让它们通过网线聊上天我前后做过好几个这类异构PLC通信的项目从早期的串口Modbus RTU到后来的开放式以太网踩过的坑不算少。这篇内容就围绕S7-1200和三菱Q系列之间的开放式以太网通信展开把选型逻辑、参数配置、程序编写、联调排错这几个环节讲透。不管你是刚接触异构通信的新手还是已经用过但总在细节上翻车的同行应该都能从里面找到能直接用的东西。先明确一个前提这里说的“开放式以太网通信”指的是基于标准TCP/IP协议栈的Socket通信方式。S7-1200这边用TSEND_C/TRCV_C或者TCON/TDISCON这套指令三菱Q系列那边用内置以太网端口的Open/Close/Recv/Send指令或者QJ71E71系列以太网模块的对应指令。双方不依赖任何专用协议网关直接通过TCP连接收发数据。这种方式的优点是灵活、数据量大、实时性够用缺点是需要自己定义应用层的数据格式没有现成的协议规范可以照搬。为什么不用Modbus TCP这是个好问题。Modbus TCP确实更标准化但它的数据区有限线圈和寄存器传输大量结构化数据时不够灵活。而且S7-1200做Modbus TCP服务器需要调用MB_SERVER指令三菱Q系列做客户端需要额外配置两边都要改工作量未必比Socket方式小。Socket方式虽然要自己定协议但一旦跑通后续扩展非常方便。注意选择通信方案时先确认双方PLC的以太网端口是否支持Socket通信。S7-1200全系CPU都支持三菱Q系列需要确认CPU型号是否自带以太网口如果没有则需要加装QJ71E71系列模块。2. 通信方案选型为什么是TCP而不是UDP2.1 TCP和UDP在这个场景下的真实差异很多人一上来就问“用TCP还是UDP”其实这个问题的答案在工业现场非常明确——绝大多数情况下选TCP。原因不在于TCP“更高级”而在于工业数据对丢包的容忍度极低。一个配方参数丢了可能导致整批产品报废一个状态信号丢了可能让操作员误判设备状态。UDP的优势是快、开销小但它不保证送达、不保证顺序。在局域网环境里UDP的丢包率通常很低但“通常很低”不等于“不会发生”。我见过一个案例用UDP传工位计数结果因为网络里接了一台广播风暴的设备计数器偶尔跳变排查了两天才定位到问题。换成TCP之后类似问题再没出现过。TCP的握手、确认、重传机制虽然增加了开销但在百兆甚至千兆局域网里这点开销完全可以忽略。S7-1200和三菱Q系列的以太网端口都是百兆起步传几百字节的数据周期在10ms级别对绝大多数产线应用来说绰绰有余。2.2 谁做服务器、谁做客户端这是第二个要定的事。TCP通信必须有明确的客户端和服务器角色。我的经验是把数据主动发起方设为客户端把数据响应方设为服务器。但更关键的是看哪边更容易做被动监听。S7-1200做TCP服务器非常方便用TCON指令监听一个端口等客户端来连就行。三菱Q系列做客户端也很成熟用Open指令主动去连对方的IP和端口。所以常见的组合是三菱Q系列做客户端S7-1200做服务器。但反过来也不是不行。如果三菱Q系列那边需要同时和多个设备通信把它设成服务器、让S7-1200去连它也能跑通。选型的时候主要考虑两点一是哪边的程序改动量小二是哪边的网络位置更适合作被动方比如经过防火墙或者NAT的情况。对比项三菱Q做客户端 S7-1200做服务器S7-1200做客户端 三菱Q做服务器连接建立Q系列主动发起S7-1200监听S7-1200主动发起Q系列监听程序复杂度S7-1200侧用TCONTRCV/TSENDS7-1200侧用TCONTSEND/TRCV断线重连Q系列侧需要做重连逻辑S7-1200侧需要做重连逻辑推荐场景Q系列需要连多个上位设备S7-1200需要连多个从站设备2.3 数据格式的约定双方必须提前谈好Socket通信最大的“坑”不在于技术本身而在于双方对数据格式的理解不一致。我见过太多项目两边程序都写完了一联调发现数据全是乱的——这边发的是大端序那边按小端序解析这边发的是浮点数那边当成整数读。所以在动手写程序之前必须先把数据格式定死。至少要明确以下几点字节序S7-1200默认是大端序高字节在前三菱Q系列默认是小端序低字节在前。这是最容易出问题的地方后面会详细讲怎么处理。数据类型每个数据项是整数、浮点数还是字符串各占几个字节数据长度每次发送的字节数是否固定如果可变长度信息放在哪里校验方式是否需要加校验码如果加用哪种校验异或、CRC16等心跳机制是否需要定期发送心跳包来检测连接状态把这些写进一份简单的通信协议文档双方各留一份联调的时候对着文档排查效率会高很多。3. S7-1200侧的配置与程序编写3.1 硬件组态和连接参数设置在博途TIA Portal里首先要在硬件组态中确认S7-1200的以太网端口已经启用。打开设备视图双击PROFINET接口在“以太网地址”里设置IP地址和子网掩码。假设我们设成192.168.1.10子网掩码255.255.255.0。这里有个细节容易被忽略如果S7-1200同时连接了其他PROFINET设备比如远程IO那么它的以太网端口已经在被PROFINET协议使用。这并不影响TCP Socket通信因为PROFINET和TCP/IP可以共用同一个物理端口但需要在组态时确认没有端口冲突。接下来在“保护”设置里确认“允许来自远程对象的PUT/GET通信访问”是否勾选。这个选项主要影响S7通信对开放式TCP通信不是必须的但勾上没坏处。3.2 用TCON建立TCP连接S7-1200做TCP服务器时核心指令是TCON。在博途的指令树里找到“通信 开放式用户通信 TCON”拖到程序块里。TCON的输入参数需要配置一个TCON_IP_v4结构体关键字段包括InterfaceId接口硬件标识符通常填64内置以太网口ID连接ID自己定义一个数值比如1ConnectionType连接类型TCP填16#0BActiveEstablished主动/被动建立服务器填FALSERemoteAddress远程IP地址服务器模式下可以填0.0.0.0LocalPort本地监听端口比如2000RemotePort远程端口服务器模式下可以填0这些参数在博途里可以通过“连接参数”对话框图形化配置也可以直接在DB块里定义。我习惯用图形化配置因为不容易填错。TCON指令的REQ引脚需要一个上升沿触发。通常用一个时钟脉冲比如1Hz来触发或者用首次扫描位触发一次。如果连接断开需要重新触发REQ来重建连接。// TCON调用示例SCL语言 TCON_DB(REQ : FirstScan, ID : 1, CONNECT : TCON_Config, DONE TCON_Done, BUSY TCON_Busy, ERROR TCON_Error, STATUS TCON_Status);3.3 用TRCV_C接收数据连接建立之后就可以用TRCV_C指令接收数据了。TRCV_C是“带连接的接收”它会自动管理连接状态比单独的TRCV指令更方便。TRCV_C的关键参数EN_R使能接收通常一直给TRUEDATA接收数据缓冲区指向一个数组或DB块LEN期望接收的字节数DONE接收完成标志RCVD_LEN实际接收到的字节数这里有个非常重要的点TRCV_C的LEN参数指定的是期望接收的最大字节数实际接收到的字节数由RCVD_LEN返回。如果对方发来的数据长度不固定就需要根据RCVD_LEN来判断实际有效数据。// TRCV_C调用示例 TRCV_C_DB(EN_R : TRUE, DATA : RecvBuffer, LEN : 100, DONE Recv_Done, BUSY Recv_Busy, ERROR Recv_Error, STATUS Recv_Status, RCVD_LEN Recv_Length);3.4 用TSEND_C发送数据发送数据用TSEND_C指令参数和TRCV_C类似REQ发送请求上升沿触发DATA发送数据缓冲区LEN发送字节数DONE发送完成ERROR错误标志发送的时候要注意如果上一次发送还没完成BUSY为TRUE不要再次触发REQ。通常用一个状态机来控制发送节奏或者用DONE信号的上升沿来触发下一次发送。// TSEND_C调用示例 TSEND_C_DB(REQ : Send_Trigger, DATA : SendBuffer, LEN : 50, DONE Send_Done, BUSY Send_Busy, ERROR Send_Error, STATUS Send_Status);3.5 字节序处理S7-1200侧的关键操作前面提到S7-1200是大端序三菱Q系列是小端序。这意味着一个16位整数0x1234S7-1200发送时字节顺序是0x12、0x34而三菱Q系列期望的是0x34、0x12。处理方式有两种方案一在S7-1200侧做字节交换。用SWAP指令或者自己写逻辑把每个多字节数据的高低字节对调。博途里有现成的SWAP指令可以对WORD、DWORD进行操作。方案二在三菱Q系列侧做字节交换。三菱的GX Works2/3里也有对应的交换指令。我的建议是在S7-1200侧处理因为博途的SWAP指令用起来更直观而且S7-1200的程序通常结构更清晰后期维护方便。// 字节交换示例将WORD类型数据高低字节对调 Swap_Result : SWAP(Original_Word);对于浮点数REAL字节交换要更复杂一些因为涉及4个字节的重新排列。通常的做法是把REAL转成DWORD做字节交换后再转回REAL。或者更简单的方式是双方约定浮点数用整数传输比如乘以1000后传整数接收方再除以1000。这样虽然损失一点精度但避免了字节序的麻烦。4. 三菱Q系列侧的配置与程序编写4.1 内置以太网端口的参数设置三菱Q系列的以太网设置需要在GX Works2或GX Works3里完成。打开“PLC参数”对话框找到“内置以太网端口设置”里面有几个关键页面基本设置设置IP地址、子网掩码、默认网关。假设设成192.168.1.20子网掩码255.255.255.0。打开设置这是最关键的部分。需要在这里配置TCP连接参数。对于做客户端的场景需要设置协议TCP打开方式Active主动对方IP地址192.168.1.10S7-1200的IP对方端口号2000S7-1200监听的端口本机端口号可以自动分配也可以指定一个固定值初始设置设置通信超时时间、重试次数等。超时时间建议设长一点比如10秒避免网络抖动导致误判断线。4.2 用OPEN指令建立连接三菱Q系列的OPEN指令用于建立TCP连接。指令格式大致如下OPEN U0 // 打开通道0但实际使用中更常见的是用SP.OPEN指令或者直接在参数里设置“始终打开”。如果选择“始终打开”PLC上电后会自动尝试连接不需要程序里额外调用OPEN指令。我个人的习惯是用程序控制打开因为这样可以在连接断开后做重连逻辑。具体做法是用一个定时器每隔几秒检测一次连接状态如果断开就重新触发OPEN。4.3 用RECV指令接收数据三菱Q系列的RECV指令用于接收TCP数据。关键参数包括通道号对应打开设置里的通道接收数据存储地址比如D1000开始接收字节数指定最大接收长度完成标志接收完成后置位// RECV指令示例 RECV U0 D1000 K100 M100这行指令的意思是从通道0接收最多100字节的数据存储到D1000开始的寄存器区域完成标志放到M100。4.4 用SEND指令发送数据SEND指令用于发送数据// SEND指令示例 SEND U0 D2000 K50 M200从D2000开始发送50字节的数据通过通道0发出完成标志放到M200。4.5 三菱侧的字节序处理如果选择在三菱侧做字节交换可以用SWAP指令或者自己写逻辑。三菱的SWAP指令可以对16位数据进行高低字节交换。对于32位数据需要分别对高16位和低16位做交换然后再交换两个16位字的位置。// 32位数据字节交换示例 // 假设原始数据在D100低16位和D101高16位 // 先交换D100的高低字节 SWAP D100 // 再交换D101的高低字节 SWAP D101 // 最后交换D100和D101的位置 MOV D100 D200 MOV D101 D100 MOV D200 D101这段逻辑看起来有点绕但实际用起来很稳定。如果数据量不大也可以直接在S7-1200侧处理三菱侧就不需要做任何转换。5. 联调阶段最容易翻车的几个点5.1 连接建立不起来先查这五个地方联调第一步就是看连接能不能建起来。如果TCON的ERROR灯亮了或者三菱侧的OPEN指令报错按以下顺序排查第一IP地址和端口号是否匹配。这是最基础但也最容易出错的。S7-1200监听的端口是2000三菱侧就要连2000不能连2001。IP地址也要确认没有输错。第二子网掩码是否一致。如果两边子网掩码不同可能在同一个交换机下也ping不通。比如一边是255.255.255.0另一边是255.255.0.0虽然IP看起来在同一个网段但实际通信可能有问题。第三防火墙是否拦截。Windows防火墙或者交换机上的ACL规则可能拦截了TCP连接。可以先用ping命令测试网络连通性再用telnet测试端口是否开放。第四S7-1200的TCON配置是否正确。特别是ActiveEstablished参数服务器必须设为FALSE如果设成TRUE就会变成主动连接导致双方都在等对方连。第五三菱侧的打开设置是否生效。修改完参数后需要重新下载到PLC并且断电重启一次有些参数需要重启才能生效。5.2 数据收得到但全是乱码字节序和数据类型排查连接通了数据也收得到了但解析出来全是乱码或者数值完全不对。这种情况九成以上是字节序问题。排查方法先发一个已知的固定值比如整数1看接收方读到的是什么。如果S7-1200发的是0x0001大端三菱侧按小端解析会读成0x0100也就是256。如果看到256那就确认是字节序问题。另一个常见问题是数据类型不匹配。比如S7-1200发的是REAL4字节浮点数三菱侧按16位整数解析结果肯定不对。这时候需要双方对照通信协议文档确认每个数据项的类型和长度。5.3 通信时断时续超时和心跳的设置技巧有些项目跑起来之后通信会偶尔断开过一会儿又自动恢复。这种“时断时续”的问题最难排查因为不是必现的。常见原因有三个一是网络负载过高。如果局域网里同时跑着视频流、大文件传输等占用带宽的应用TCP连接可能因为超时而断开。解决办法是给PLC通信划分独立的VLAN或者至少用独立的交换机。二是超时时间设得太短。三菱侧默认的通信超时可能是几秒如果网络稍有抖动就断开了。建议把超时时间设到10秒以上重试次数设到3次以上。三是没有心跳机制。TCP连接在长时间没有数据往来时可能被中间的网络设备如交换机、路由器回收。解决办法是双方约定一个心跳包比如每隔5秒发一个固定格式的空包保持连接活跃。我在一个项目里遇到过交换机每隔30分钟回收空闲TCP连接的问题加了心跳之后彻底解决。心跳包不需要很复杂发一个固定的字节序列就行接收方收到后直接丢弃不做任何处理。5.4 大数据量传输时的缓冲区管理当传输的数据量比较大比如超过500字节时可能会遇到接收缓冲区溢出或者数据被截断的问题。S7-1200的TRCV_C指令如果LEN设得太小超出的数据会被丢弃。如果LEN设得太大又会浪费内存。建议根据实际数据量设置一个合理的值比如实际数据最大200字节LEN就设250。三菱侧的RECV指令也有类似问题。接收字节数要设得比实际数据量稍大一些但不要太大否则会占用过多的寄存器空间。另外如果数据量确实很大建议分片传输。比如每次只发100字节接收方收完一片再收下一片。这样虽然增加了协议复杂度但稳定性会好很多。6. 几个实战中攒下来的经验6.1 用状态机管理通信流程不管是S7-1200还是三菱Q系列通信程序都不应该写成“一坨”线性逻辑。我习惯用一个简单的状态机来管理状态0等待连接建立状态1连接已建立等待发送请求状态2发送中状态3等待接收状态4接收完成处理数据状态5错误处理等待重连每个状态只做一件事状态之间的转换条件清晰明确。这样后期排查问题的时候看一眼当前状态就知道程序卡在哪一步。6.2 通信协议文档比程序更重要我见过太多项目程序写得漂漂亮亮但通信协议文档只有一张草稿纸。结果半年后设备要改造没人记得当初的数据格式是什么只能重新抓包分析。建议在项目开始阶段就写一份简单的通信协议文档至少包含双方IP地址和端口号数据方向谁发给谁每个数据项的偏移地址、数据类型、长度、含义字节序约定心跳包格式和周期错误处理约定这份文档不需要很正式用Excel或者Word写清楚就行。但一定要双方确认签字避免后期扯皮。6.3 先用调试工具验证再写PLC程序在写PLC程序之前建议先用调试工具验证通信链路。S7-1200侧可以用“网络调试助手”之类的工具模拟客户端三菱侧可以用类似的工具模拟服务器。先确认IP、端口、数据格式都没问题再把逻辑搬到PLC里。这样做的好处是排查问题的时候可以明确区分是“网络问题”还是“PLC程序问题”。如果调试工具能通PLC程序不通那问题肯定在程序里如果调试工具都不通那就是网络或参数配置的问题。6.4 断线重连逻辑必须做工业现场的网络环境不像办公室那么稳定交换机重启、网线松动、设备断电都是常有的事。如果通信程序没有断线重连逻辑一旦断开就需要人工重启PLC这在产线上是不可接受的。S7-1200侧的TCON指令如果连接断开ERROR会置位。这时候需要复位REQ等几个扫描周期后再重新触发。三菱侧类似检测到OPEN指令报错后需要先CLOSE再重新OPEN。重连逻辑要注意一点不要频繁重连。如果对方设备断电了你每秒重连一次会给网络带来不必要的负担。建议重连间隔设为3到5秒既能快速恢复又不会造成网络风暴。6.5 数据校验简单但有效虽然TCP本身有校验机制但在应用层再加一层简单校验能过滤掉很多莫名其妙的问题。最简单的校验方式是异或校验把所有数据字节异或得到一个校验字节附在数据末尾。接收方重新计算异或值和收到的校验字节对比不一致就丢弃这包数据。异或校验的计算量很小PLC完全能承受。虽然它不能纠正错误但能检测出大部分传输错误。对于可靠性要求更高的场景可以用CRC16但计算量会大一些。7. 从一次真实改造项目看完整流程最后分享一个我去年做的改造项目把整个流程串一遍。项目背景一条包装线原本用S7-1200控制后来增加了一台三菱Q系列的贴标机。需要S7-1200把产品规格参数包括产品编号、速度、温度设定值发给贴标机贴标机把贴标完成信号和故障代码回传给S7-1200。第一步确定通信方案。双方都有以太网口距离不远同一个电柜直接网线连接。选TCP三菱Q做客户端S7-1200做服务器。S7-1200监听端口2000。第二步定义数据格式。S7-1200发给贴标机的数据产品编号16位整数2字节、速度16位整数2字节、温度设定值16位整数2字节共6字节。贴标机回传的数据完成信号1位用1个字节表示、故障代码16位整数2字节共3字节。字节序统一用大端三菱侧做转换。第三步S7-1200侧编程。用TCON建立连接TRCV_C接收贴标机回传的3字节数据TSEND_C发送6字节参数。字节序不需要转换因为约定用大端。第四步三菱侧编程。用OPEN指令建立连接RECV接收6字节参数SEND发送3字节回传数据。接收到的数据做字节交换后存入D寄存器。第五步联调。先用网络调试助手模拟双方确认数据格式正确。然后下载PLC程序监控TCON和OPEN的状态。第一次联调发现贴标机回传的完成信号一直是0排查后发现是三菱侧的SEND指令没有触发。原因是完成标志M200没有正确复位导致SEND只执行了一次。加上复位逻辑后正常。第六步压力测试。连续运行24小时每隔100ms收发一次数据。期间人为断开网线再插上测试重连逻辑。重连时间大约3秒满足产线要求。这个项目从方案确定到联调完成大概用了3天时间。其中大部分时间花在数据格式确认和联调排错上真正写程序的时间不到一天。所以我的体会是异构PLC通信难点不在编程而在沟通和细节。把数据格式定清楚把字节序处理好把重连逻辑做扎实剩下的就是按部就班地配置和调试。提示如果项目中涉及多台设备通信建议给每台设备分配固定的IP地址和端口号并做好标签记录。后期维护的时候一张清晰的网络拓扑图能省下大量排查时间。