☰
西门子S7-200 SMART双机通信实战:开放式TCP全解析
2026/9/28 7:21:34 网站建设 项目流程

设备联动、远程站同步、双机冗余,做自动化项目的人迟早会碰到一个问题:两台西门子S7-200 SMART之间怎么稳定地把数据互传过去。用模拟量接线硬拉信号早就不现实了,走通信才是正路。这篇文章我直接把开放式TCP通信这套玩法拆开讲,从方案选型、IP端口规划、TCON/TSEND/TRCV指令实战,到断线重连和错误码排查,全部按我实际调试过的步骤写出来,末尾还附带一份避坑指南。刚入门PLC通信的工程师也好,第一次做双PLC项目的学生也好,照着做基本能把链路跑通,而且能少走很多弯路。

1. 通信方案怎么选:为什么我推荐开放式TCP通信

1.1 双PLC互传,还有哪些路可以走

S7-200 SMART的CPU本体自带以太网口,这意味着通信方案不止一种。我平时常用的大概有三条路线:Modbus TCP、S7协议通信(GET/PUT)、开放式TCP通信(TCON/TSEND/TRCV)。

Modbus TCP上手快,有现成的MB_CLIENT和MB_SERVER指令,适合做主从式数据交换,数据通过保持寄存器映射,调试工具也多。S7协议通信适合和西门子其他上位系统对接,需要在CPU里勾选“允许远程PUT/GET访问”,配置相对隐蔽,两个200 SMART之间互相读数据时用起来也顺手。而开放式TCP通信是直接基于TCP/IP协议栈做套接字通信,PLC自己扮演客户端或者服务器,想发什么字节就发什么字节,不受寄存器模型的限制。

从实际项目看,两台S7-200 SMART做双向对等数据互传,我最推荐开放式TCP通信。原因是它的通信模型最清晰,主动端、被动端一配就知道谁连谁;数据区直接指向V区,不用在Modbus地址映射上绕弯子;而且指令执行情况通过DONE、BUSY、ERROR和STATUS完整暴露出来,出了故障容易定位。

1.2 开放式TCP通信的原理与适用边界

TCP通信有个绕不开的概念叫“三次握手”。可以把它想象成两个人打电话:主叫方说“能听到吗”,被叫方回“听到了,你能听到我吗”,主叫方再回“听到了”,电话才正式接通。S7-200 SMART里的TCON指令,干的就是这件事。连接建立之后,TSEND发数据、TRCV收数据,双方数据通道就通了。

不过这并不意味着TCP是万能的。TCP可靠、有序、适合点对点的大块数据交互,但代价是需要维护连接状态,握手和断线重连都要时间。如果只是做设备状态广播,或者对实时性要求极高、少量丢帧也无关紧要的场景,可以考虑UDP。但双PLC互传生产数据,我一般不用UDP,数据漏一帧可能导致两台设备动作不一致,后期维护成本极高。

还有一个边界问题:开放式TCP通信适合的报文长度通常在几百字节以内。S7-200 SMART毕竟是小型PLC,数据缓冲区放在V区,过大的报文会拉长扫描周期,内存也紧张。如果动不动要传几K字节的配方数据,建议先考虑上位机做中转或改用支持更大缓冲区的CPU。

2. 开工前的硬件连接与地址规划

2.1 网线直连还是加交换机

两台PLC连接,最简单的办法是网线直连。现在的S7-200 SMART网口基本都支持自动翻转,普通直通网线插上去就能通,不一定非要交叉线。但直连只适合一对一场景,以后要接触摸屏、上位机、其他PLC,就得加一台工业交换机,顺便把网络拓扑做成星形结构,维护起来方便得多。

现场环境如果比较恶劣,交换机的选择也需要注意。我习惯用支持导轨安装的工业交换机,至少是百兆入门款,工作温度范围要覆盖现场环境。至于普通家用交换机,实验室玩玩问题不大,车间里电磁干扰一上来,丢包和通信闪断就够你折腾一整天。

接线前还有一件事必须做:确认CPU固件版本。S7-200 SMART的开放式通信指令在V2.0及以后版本支持得比较完整,V1.0固件的CPU建议先升级固件再做项目,不然部分指令块可能用不了,或者指令参数有差异。

2.2 IP与端口规划表

通信能不能正常跑起来,一半看IP规划。两个PLC的IP必须在一个网段,子网掩码一致,IP地址不能冲突。端口号要避开常见服务端口,工控通信里我习惯用1024以上的端口,常见的选择有2000、2001、5000等。

我这里用一个实际项目的典型配置举例。A机作为主动端(客户端),B机作为被动端(服务器):

设备IP地址子网掩码Active/Passive本地端口远程IP远程端口
PLC-A192.168.1.10255.255.255.0Active2000192.168.1.202000
PLC-B192.168.1.20255.255.255.0Passive2000192.168.1.102000

端口可以两端都用2000,只要IP不同就不会冲突。需要注意一点:A机作为Active端,配置时要填B机的IP和端口;B机作为Passive端,主要在本地监听,远程IP和端口可以留空或者填对方信息,不同固件版本界面略有区别。

规划完IP,建议顺手把设备IP、端口、用途贴到端子排或电柜门上。项目调试完两三个月再回去改程序,如果没留标签,光查IP对应关系就能让你翻半天图纸。

2.3 软件里的网络参数设置

在STEP 7-Micro/WIN SMART里设置IP,通过菜单“通信—以太网”找到在线CPU,修改IP地址后下载到PLC。也可以把IP设置写进程序,通过System Block下传到CPU。这里有个不太明显但容易踩的坑:改动IP后,上位机软件和PLC之间的逻辑连接会断开,需要重新搜索CPU后再次建立连接;如果修改后不能通信,检查一下电脑网卡IP是不是和PLC在同一个网段。

下载完程序,记得做一次断电重启再观察IP是否生效。有些现场项目里,有人改了IP后直接运行,结果通信还是用的旧IP,就是因为没有完全断电重启,CPU还在用缓存中的网络参数。重启这事,说大不大,说小不小,吃一次亏就记住了。

3. 从零搭建通信程序:TCON、TSEND、TRCV这样用

3.1 连接描述符配置:先把“电话线”接好

在STEP 7-Micro/WIN SMART的指令树里,找到“通信—连接”配置项,新建一个连接,协议选择TCP,然后把主动端/被动端、本地端口、远程IP、远程端口填进去。这个连接表就是PLC的“电话本”,TCON指令靠连接ID去查找对应的连接参数。ID号可以随便取吗?不行,ID必须和指令块里填的ID严格对应,同时连接表里一个ID只能对应一条连接。

连接描述符配置得好不好,直接影响后续指令的状态。填被动端时,如果软件要求填远程IP,而你又不知道对方IP,可以先用目标IP占位,后续再改。不过稳妥起见,正式开工前把两边的IP、端口、主动被动方向统一确认一遍,这个表就是你们的通信协议文档了。

3.2 TCON建连:TCP三次握手是怎么来的

TCON负责发起TCP连接,参数有REQ、ID、DONE、BUSY、ERROR、STATUS。REQ需要上升沿触发,只要有一次0到1的跳变,CPU就会去按连接表里的配置发起连接。DONE置1表示连接建立成功;BUSY表示正在处理中;STATUS输出错误码,排查时先看它。

程序里我习惯用首次扫描标志SM0.1置位一个M位,再用这个M位去触发TCON的REQ,连接建立后不再重复触发。为什么不能一直用SM0.0去触发?因为TCON的REQ是边沿敏感的,SM0.0每个扫描周期都是1,不会产生上升沿,连接根本无法建立;就算后续逻辑里阴差阳错触发了,重复发建连请求也会导致连接状态混乱。

TCON的STATUS只要不是0,就说明建连失败。最常见的错误码是80C4和80C8,前者表示连接正在建立中,后者表示连接完全没建立起来。遇到80C8,优先查IP、端口、网线,这三个问题占了八成的现场故障。

3.3 TSEND和TRCV:收发数据并不难

连接建立后,用TSEND发送数据,用TRCV接收数据。TSEND的REQ也是上升沿触发,参数里LEN表示发送的字节数,DATA是发送缓冲区起始地址的指针。TRCV的EN_R是电平使能,一般直接用SM0.0一直开启,LEN表示期望接收的最大字节数,DATA是接收缓冲区的起始地址。

这里有一个非常重要、也是很多人反复踩坑的点:TRCV的LEN一定要大于等于对方实际发送的字节数。如果发送端发了32个字节,接收端LEN只配了16,数据就收不完整,要么报错,要么一直等不到DONE。我一般把两端的LEN设成相同数值,并且把报文长度固定下来,不搞“发多少算多少”的自由格式。通信协议这种东西,越固定越不容易出问题。

TSEND和TRCV的DONE/BUSY/ERROR/STATUS,调试阶段全部要接出来监控。尤其STATUS,一旦通信异常,它是第一手线索。有人图省事不关注状态位,通信断了还在那拼命查网线,查了半天才发现是发送长度超了,这就很浪费时间。

3.4 报文格式约定:不要只丢一堆裸数据

双PLC互传,很多人的第一反应是把要传的M区或V区直接发过去。这种做法在数据量小、两台设备固定不变的时候可以跑,但一旦涉及多台设备或者后期加功能,裸数据交换会变得极其难维护。我建议从一开始就定义一套简单的报文格式。

比如定义32字节的固定报文:

偏移字节数内容说明
VB0-VB12帧头,固定0x16 0x55
VB2-VB32心跳计数,每100ms加1
VB4-VB52设备状态字
VB6-VB72预留
VB8-VB3124用户数据区

发送方只管按这个格式填充V区,接收方收到后先判断帧头,再取数据。帧头不一致的报文直接丢弃,可以有效避免程序里出现“数据错位”这种最难查的怪问题。心跳计数也是必不可少的设计,它是后面断线重连逻辑的重要输入,如果链路断了,心跳计数就会停止变化。

4. 完整实例:两台PLC以100ms周期互传32字节

4.1 程序框架与初始化

下面这个例子,配置与第2节的表格一致:PLC-A为Active端,PLC-B为Passive端,双方端口2000,通过一台交换机互联。程序框架分成三块:初始化、数据发送、数据接收。

初始化部分的STL代码可以这样写:

// 首次扫描初始化 LD SM0.1 MOVB 100, SMB34 // 定时中断0间隔100ms ATCH INT_0, 10 // 绑定中断程序INT_0到定时中断0 ENI // 全局开中断

注意SMB34的单位是毫秒,取值范围1到255,这里设100就是100ms一次中断。如果配成1000,CPU会报参数错误,因为超过255了。别小看这个细节,我见过有人在程序里写MOVB 1000, SMB34,编译不报错,运行后中断根本不工作,查了半天才找到原因。

发送缓冲区和接收缓冲区的地址规划如下:

数据区地址范围长度说明
PLC-A发送区VB0-VB3132字节A发给B的数据
PLC-A接收区VB100-VB13132字节B发给A的数据
PLC-B发送区VB0-VB3132字节B发给A的数据
PLC-B接收区VB100-VB13132字节A发给B的数据

两边程序结构相同,只是TCON触发方式和连接表配置不同。A机作为Active端上电后主动去建连,B机作为Passive端只要配置好连接表,程序里同样跑TCON等待连接接入。这里不要有误解:被动端不是说不用调用TCON,它也得调用TCON去被动接收连接,只是连接表里主动/被动模式不一样。

4.2 发送节奏与定时中断的选择

双PLC之间数据交换,发送节奏一定要控制。最忌讳的做法是把TSEND直接放在主程序里每个扫描周期都触发,那样不仅浪费CPU资源,还容易把通信缓冲区塞满。我用定时中断来做节奏控制,100ms发一次,32字节的报文对S7-200 SMART来说压力很小。

发送触发的STL逻辑可以放在定时中断程序里,也可以放在主循环里用定时器产生脉冲。我习惯用T37定时器在主循环生成一个100ms脉冲,然后取上升沿触发TSEND:

// 100ms脉冲生成 LDN T37 TON T37, 10 // 100ms定时器 // 上升沿触发TSEND LD T37 EU TSEND ID:=1, REQ:=T37, LEN:=32, DATA:=&VB0, DONE:=M2.1, BUSY:=M2.2, ERROR:=M2.3, STATUS:=MW22

接收部分用TRCV一直使能:

LD SM0.0 TRCV ID:=1, EN_R:=SM0.0, LEN:=32, DATA:=&VB100, DONE:=M3.0, BUSY:=M3.1, ERROR:=M3.2, STATUS:=MW24

TSEND的REQ为什么不能直接接SM0.0?因为上升沿检测的原理是当前扫描周期为1、上一扫描周期为0时才会触发。SM0.0恒为1,永远不会有上升沿。用T37置位产生一个很窄的脉冲,正好让TSEND识别到一次上升沿,完成一次发送。

4.3 断线检测与自动重连

通信链路断开的场景很常见,网线松动、交换机掉电、对方PLC重启,任何一次中断都可能导致连接失效。没有断线检测和重连机制,系统就要人工重启才能恢复,这在无人值守的场合是不可接受的。

断线检测的核心是心跳。发送方在报文的VB2-VB3位置放一个心跳计数,每100ms加1。接收方检测心跳计数的值是否持续变化,如果连续2秒没有变化,就判断链路断开。检测逻辑可以用一个定时器来做,每100ms比较一次VW2(对方报文的接收值)和旧值,如果相等就累加超时计数,超过20次(2秒)就置位断线标志。

断线后的重连逻辑由主动端完成。重连时先将TCON的REQ复位,等待一定时间后重新置位,让TCON重新发起TCP连接。如果软件版本支持TDISCON指令,也可以先主动断开连接,再重新建连,这样状态更干净。Passive端不需要做重连动作,它只要一直保持TRCV使能,等主动端重新连上来即可。

还有一点要注意:重连不要死循环。我习惯设计成“每5秒尝试重连一次,连续失败3次后停止,并输出报警”,这样既保证恢复能力,又避免通信模块被反复建连拖垮。

5. 现场排查实录:错误码、怪现象、稳定化技巧

5.1 常用STATUS错误码速查

调试过程中,STATUS状态字是排障的第一参考。我整理了实际项目中高频出现的几个错误码,不同固件版本可能略有差异,以手册为准:

错误码(十六进制)含义处理建议
0x0000无错误正常,不用管
0x80C4连接正在建立中等待,确认另一端是否在线
0x80C8连接未建立查IP、端口、网线、Active/Passive配置
0x8709连接ID配置无效检查连接表ID与指令ID是否一致
0x8721数据区指针错误检查DATA指针是否指向有效V区地址

80C8是最常见的,我之前帮朋友调一个项目,两台PLC怎么都连不上,查了半小时,最后发现被动端连接表里把远程端口填成了502,主动端填的是2000,两边对不上,TCP握手根本完成不了。端口号两边必须严格一致,这是最容易被忽视的问题。

5.2 我踩过的三个经典坑

第一个坑是TRCV的LEN问题。接收端的LEN必须大于等于发送端的实际发送长度。我在一个项目里用TSEND发32字节,接收端LEN设的16,结果TRCV的DONE一直不置位,数据看起来“进去了”但程序就是拿不到。后来把LEN改成32,立刻就好了。

第二个坑是重复触发TCON。早期我做重连逻辑时,把TCON的REQ直接接到了断线检测标志上,没有处理上升沿。结果连接断开后,REQ保持为1,TCON不会重新建立连接,必须复位再置位才行。后来学乖了,重连时序做成了状态机:断线检测——复位REQ——延时3秒——重新触发REQ。

第三个坑是报文内容错位。一开始我没约定帧头,两台PLC各自维护自己的数据区,结果程序升级后一端的数据格式改了,另一端还在按老格式解析,现场设备偶尔动作不对,排查相当煎熬。加了帧头之后,只要帧头不对就丢弃,问题迅速暴露。

5.3 长期运行稳定性优化心得

项目交付以后,稳定运行比通信调通更重要。根据我的经验,有几点值得做好。

通信数据区尽量用独立的V区段,并且把发送区和接收区分开,不要和业务逻辑共用地址。S7-200 SMART的数据区本身不大,规划好地址段,能避免很多数据覆盖的隐性故障。

发送节奏、心跳周期、超时时间这些参数要写在项目说明里。通信程序是逻辑性很强的东西,半年后再看代码,如果没有文档,很难记得当初为什么用100ms而不是500ms。我一般会在程序文件头部的注释里写明通信参数,注释这东西,写的时候花一分钟,排查的时候省一个小时。

有条件的话,在系统里加一个“通信正常”的指示灯或HMI报警位。现场维护人员不需要看懂STATUS代码,只需要知道通信是不是好的。这个逻辑很简单:心跳在更新,就置位通信正常;心跳超时,就置位通信报警。看似不起眼,但现场运维体验差别很大。

我自己的感受是,通信类项目最怕的不是通信本身,而是“没有节制的自由配置”。IP乱起、端口乱填、报文格式随手改的人,等出了问题全都一脸懵。规划先行、协议先行、心跳先行,这三点做到位,后期基本不会有大坑。这套方法我用了很多年,从S7-200 SMART到S7-1200/1500都适用,希望能给你省下几个调试的夜晚。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询