
1. 为什么PUT/GET通讯总在关键时刻掉链子搞西门子S7-1200的同行十个里有八个在PUT/GET上栽过跟头。现象往往很统一TIA Portal里编译没报错连接也组态了下载到PLC后一运行要么报“连接被拒绝”要么状态字一直停在W#16#8090或者W#16#80A1更邪门的是有时候重启一下就好了过两天又犯病。你翻遍西门子官方手册参数对着抄了一遍又一遍问题依旧。这个标题里提到的“从DB块复制到自动连接的5个关键点”其实点出了一个非常典型的场景很多工程师在配置S7-1200之间的PUT/GET通讯时习惯性地把对方DB块的数据结构直接复制过来然后在本地建一个一模一样的DB块再在TIA Portal里手动建立连接。这套流程看起来天经地义但恰恰是错误的高发区。因为S7-1200的PUT/GET通讯本质上是一种基于连接的单向数据读写机制它跟你用过的S7-200的PPI、S7-300的MPI通讯在底层逻辑上完全不是一回事。我见过太多项目现场调试时PUT/GET跑得好好的设备一交付运行几个月后突然通讯中断客户电话打过来你远程连上去一看连接资源被占满了。也见过两个S7-1200之间明明网线直连Ping得通但PUT指令就是报W#16#80C0最后发现是两边CPU的固件版本差异导致连接参数协商失败。这些坑手册上不会写得那么细只有真正在产线上熬过夜的人才知道。这篇文章就是要把这些年在S7-1200 PUT/GET通讯上踩过的雷、绕过的弯掰开揉碎了讲清楚。不管你是刚接触西门子PLC的新手还是做了多年项目的老手只要你的系统里涉及S7-1200之间的数据交换尤其是用PUT/GET这种方式这里面的五个关键点你迟早会碰到。我会从连接机制、DB块处理、参数配置、资源管理、故障排查五个维度把每个环节的“为什么”和“怎么做”都说明白让你下次再遇到报错时不用再靠重启碰运气。2. 先搞懂S7-1200 PUT/GET的底层逻辑再动手2.1 PUT/GET不是“读写”是“远程访问”很多人把PUT/GET理解成“我把数据推过去你把数据拉过来”这个理解在应用层没错但在实现层完全跑偏了。S7-1200的PUT/GET通讯本质上是客户端主动发起的远程内存访问。PUT指令的执行过程是本地CPU作为客户端通过已建立的S7连接向远程CPU发起写请求远程CPU的通讯处理器接收请求后直接写入指定的DB块或M区。GET指令同理是本地CPU向远程CPU发起读请求。这里的关键在于远程CPU不需要编写任何接收程序。你不需要在对方PLC里写什么“接收中断”或者“数据解析”逻辑只要对方CPU允许PUT/GET访问并且你指定的地址存在且长度匹配数据就直接进去了。这跟Modbus TCP完全不一样Modbus需要对方有服务器程序在跑而PUT/GET是西门子内部的一种“后门”式访问机制。注意正因为这种机制绕过了用户程序所以安全性很低。任何知道IP和地址的人都能读写你的数据。在实际项目中如果涉及关键参数一定要在程序里做校验不能完全依赖PUT/GET的写入结果。2.2 连接是“单边组态”但两边都要设置这是最容易让人迷惑的地方。在TIA Portal里组态PUT/GET通讯时你只需要在主动发起通讯的那一侧也就是调用PUT/GET指令的那一侧建立连接。被动侧被读写的那个PLC不需要在TIA Portal里建立对应的连接组态。但是被动侧必须做两件事第一在硬件配置里勾选“允许来自远程对象的PUT/GET通讯访问”第二确保要访问的DB块属性里取消勾选“优化的块访问”。我见过一个案例两个S7-1200做PUT/GET主动侧组态没问题被动侧也勾了“允许PUT/GET”但就是连不上。查了半天发现被动侧那个DB块是优化的绝对地址访问不了。因为PUT/GET指令里填的地址是绝对地址比如DB1.DBX0.0 BYTE 10如果DB块是优化的这个地址根本不存在。把“优化的块访问”取消重新编译下载问题立刻解决。2.3 连接资源是有限且需要管理的S7-1200的CPU连接资源不是无限的。以CPU 1214C为例它的最大连接资源是16个其中PUT/GET连接、HMI连接、编程连接、Web连接都要从这16个里扣。如果你同时用了PUT/GET跟三台设备通讯又挂了两个HMI还开着编程电脑在线连接资源很快就见底了。更麻烦的是PUT/GET连接是静态建立的不会自动释放。也就是说只要你的程序在跑连接就一直占着。如果因为网络闪断导致连接异常而你的程序没有做重连机制这个连接资源可能就一直处于“僵死”状态新的连接建不起来。这时候你重启PLC连接资源被清空通讯恢复但过一段时间又满了。这就是为什么“重启就好过两天又坏”的根本原因。3. DB块处理从复制到映射的五个关键点3.1 关键点一被动侧DB块必须取消优化访问这是所有PUT/GET通讯的前提条件没有例外。S7-1200默认新建的DB块是“优化的块访问”这种块在PLC内部是按符号名寻址的没有固定的绝对地址。而PUT/GET指令在组态时你需要填写的是绝对地址比如DB2.DBX0.0 BYTE 20。如果DB块是优化的这个地址在编译时就会报错或者虽然编译通过但运行时找不到地址。操作步骤很简单在项目树里右键点击被动侧的DB块选择“属性”在“属性”选项卡里找到“优化的块访问”复选框取消勾选。然后编译整个项目下载到被动侧PLC。注意取消优化访问后DB块内的变量地址会重新分配你需要重新确认每个变量的绝对地址确保跟主动侧PUT/GET指令里填的地址一致。实操心得我习惯在DB块命名时就加上“_abs”后缀比如Data_abs提醒自己这个块是绝对地址访问的不能优化。另外取消优化后DB块的最大长度会有限制具体取决于CPU型号一般不超过64KB对于大多数应用足够了。3.2 关键点二主动侧不要直接复制被动侧DB块标题里说的“从DB块复制”指的就是这个动作很多工程师为了省事直接把被动侧的DB块复制一份到主动侧项目里然后PUT/GET指令里填的地址就照着这个复制过来的块填。这个做法本身没错但问题出在复制过来的DB块默认是优化的。因为TIA Portal新建DB块时默认勾选优化访问你复制过来之后如果没有手动取消这个块就是优化的里面的地址跟被动侧的实际地址对不上。更隐蔽的问题是即使你取消了优化两个DB块里的变量顺序、数据类型、对齐方式也可能因为编译器的版本差异而不同。比如被动侧用的是TIA Portal V15主动侧用的是V16同样的变量定义编译后的地址偏移可能差几个字节。所以我的建议是不要复制DB块而是手动在主动侧建立一个“映射DB块”这个块只用来存放PUT/GET要交换的数据变量定义严格按照被动侧的绝对地址来排列并且显式取消优化访问。3.3 关键点三地址偏移量要逐字节核对PUT/GET指令的管脚ADDR_1填的是远程CPU的地址格式是DB号.起始字节.起始位 数据类型 长度。比如DB2.DBX10.0 BYTE 50表示从DB2的第10个字节开始读写50个字节。这里最容易出错的是起始字节的计算。假设被动侧DB块里定义了三个变量Speed是Real占4字节起始地址0Status是Bool占1位起始地址4.0Count是Int占2字节起始地址6。那么Count的绝对地址是DB2.DBW6。如果你在PUT指令里写DB2.DBX6.0 INT 1读的就是Count。但如果你写DB2.DBX4.0 INT 1读的就是Status和后面一个字节的组合数据完全错乱。我自己的做法是在被动侧DB块里每个变量后面都加一个注释写明绝对地址。然后在主动侧建一个Excel表格把要交换的变量、地址、长度、数据类型全部列出来PUT/GET指令组态时对着表格填填完再核对一遍。这个习惯帮我省了至少三次现场返工。3.4 关键点四数据长度要匹配不能多也不能少PUT/GET指令里的长度参数必须跟你要访问的数据长度完全一致。比如你要写一个Real长度就是4字节要写一个数组Array[0..9] of Int长度就是20字节。如果你写多了会覆盖后面不该动的数据写少了数据不完整。有一个特殊情况Bool类型的数据。PUT/GET指令里Bool是按位访问的长度填1但实际传输的是一个字节。比如你要写DB2.DBX4.0这个Bool指令里写DB2.DBX4.0 BOOL 1它会读写第4个字节的第0位。如果你要连续写8个Bool可以写DB2.DBX4.0 BYTE 1一次写一个字节然后被动侧按位解析。这样比写8条PUT指令效率高得多。3.5 关键点五建立“自动连接”不如手动确认连接TIA Portal里有一个“自动连接”的功能在组态PUT/GET时如果你不手动指定连接软件会自动创建一个连接。这个功能看起来很省事但实际上是坑最多的。因为自动创建的连接其连接ID、本地接口、远程接口都是软件自动分配的你很难控制它用的是哪个网口、哪个协议。更麻烦的是如果项目里有多个CPU、多个网段自动连接可能会选错路径。我遇到过一次两个S7-1200分别接在同一个交换机的不同VLAN里自动连接居然试图通过路由建立连接结果当然失败。后来手动指定连接明确本地接口是PLC_1.PROFINET接口_1远程接口是PLC_2.PROFINET接口_1问题解决。所以我的建议是永远手动建立连接。在“网络视图”里用鼠标拖拽的方式把两个CPU的PROFINET接口连起来然后在连接属性里确认连接类型是“S7连接”并且勾选“允许PUT/GET通讯”。这样建立的连接参数一目了然出了问题也好排查。4. 实操过程从零搭建一个稳定的PUT/GET通讯4.1 硬件与软件环境准备先说一下我这次演示用的环境两台S7-1200 CPU 1214C DC/DC/DC固件版本都是V4.4TIA Portal V16。两台PLC通过一个非管理型交换机连接IP地址分别是192.168.0.1和192.168.0.2子网掩码255.255.255.0。主动侧是PLC_1被动侧是PLC_2。软件方面TIA Portal V16已经安装了S7-1200的GSD文件不需要额外安装。如果你用的是V14或者V15操作界面略有不同但核心逻辑一样。建议尽量用V15.1以上的版本因为V14在PUT/GET连接组态上有一些已知的Bug比如连接ID冲突导致通讯不稳定。4.2 被动侧PLC_2的配置步骤第一步在PLC_2的硬件配置里双击PROFINET接口在“属性”里找到“保护”选项卡勾选“允许来自远程对象的PUT/GET通讯访问”。这个选项默认是不勾的必须手动打开。第二步新建一个全局DB块命名为Data_abs取消“优化的块访问”。在块里定义以下变量变量名数据类型绝对地址说明SpeedRealDB2.DBD0速度设定值StatusBoolDB2.DBX4.0运行状态CountIntDB2.DBW6产量计数BufferArray[0..9] of ByteDB2.DBB8数据缓冲区第三步编译整个项目下载到PLC_2。下载完成后把CPU打到RUN模式。注意被动侧不需要写任何通讯程序只要硬件配置和DB块正确就行。4.3 主动侧PLC_1的配置步骤第一步在PLC_1的硬件配置里同样勾选“允许来自远程对象的PUT/GET通讯访问”。虽然PLC_1是主动侧但有时候它也会被其他设备访问勾上没坏处。第二步在“网络视图”里把PLC_1和PLC_2的PROFINET接口用鼠标连起来。连接完成后右键点击连接线选择“属性”确认连接类型是“S7连接”并且勾选“允许PUT/GET通讯”。这里要注意连接属性里的“本地接口”和“远程接口”要确认是实际的网口不要选成虚拟接口。第三步在PLC_1里新建一个DB块命名为Map_abs同样取消优化访问。这个块用来存放从PLC_2读回来或者要写过去的数据。变量定义跟PLC_2的Data_abs一一对应地址也保持一致。第四步在OB1里调用PUT和GET指令。PUT指令的管脚配置如下REQ用一个上升沿触发比如Clock_1Hz的上升沿或者手动按钮ID填连接ID可以在连接属性里查到一般是W#16#0001这样的格式ADDR_1填DB2.DBX0.0 BYTE 20表示从PLC_2的DB2第0字节开始写20个字节SD_1填DB1.DBX0.0 BYTE 20表示从PLC_1的DB1第0字节开始取数据DONE、ERROR、STATUS分别接M区的一个位和一个字用来监控执行状态GET指令的管脚类似只是方向相反ADDR_1是远程地址RD_1是本地接收地址。4.4 参数计算与地址核对这里重点说一下地址计算。PLC_2的Data_abs块里Speed是Real占4字节地址0-3Status是Bool占1位地址4.0Count是Int占2字节地址6-7Buffer是10个Byte地址8-17。总共18个字节。所以PUT/GET的长度填20字节是安全的多出来的2个字节是填充不影响。如果你要单独读写某个变量比如只写Speed那么ADDR_1填DB2.DBX0.0 REAL 1长度是4。只读CountADDR_1填DB2.DBX6.0 INT 1长度是2。注意Bool类型不能单独用BYTE长度读写必须用BOOL长度比如DB2.DBX4.0 BOOL 1。注意PUT/GET指令的ADDR_1管脚数据类型和长度是写在字符串里的比如DB2.DBX0.0 REAL 1。这个字符串的格式必须严格遵循西门子的规定大小写敏感空格数量也有要求。写错了编译不报错但运行时报W#16#8090。4.5 下载与在线监控配置完成后先编译PLC_1下载。然后在线监控OB1观察PUT/GET指令的STATUS管脚。如果STATUS是W#16#0000DONE位为1说明通讯成功。如果STATUS是W#16#8090说明地址格式错误如果是W#16#80A1说明连接ID错误如果是W#16#80C0说明连接资源不足或者连接被拒绝。我习惯在OB1里加一个简单的状态机用ERROR位触发一个计数器如果连续10次通讯失败就置位一个报警位通知HMI显示“通讯故障”。这样比单纯看STATUS字直观得多。5. 常见问题与排查技巧实录5.1 问题速查表现象可能原因排查方法解决方案STATUSW#16#8090地址格式错误检查ADDR_1字符串格式严格按照DB号.DBX字节.位 类型 长度格式填写STATUSW#16#80A1连接ID错误在连接属性里查看实际ID把ID改成连接属性里显示的十六进制值STATUSW#16#80C0连接资源不足在线查看CPU连接资源占用减少不必要的连接或升级CPU型号通讯时好时坏网络闪断或连接僵死用Ping测试网络稳定性在程序里加心跳检测和重连逻辑数据错乱DB块优化未取消检查被动侧DB块属性取消“优化的块访问”重新编译下载编译报错“地址无效”DB块长度不够检查DB块实际长度扩大DB块长度或调整地址偏移5.2 独家避坑技巧连接资源监控S7-1200的连接资源是动态分配的但PUT/GET连接一旦建立就不会自动释放。我遇到过最极端的情况是一个项目里用了8个PUT/GET连接加上HMI和编程电脑16个连接资源全满导致新设备无法接入。后来我在程序里加了一个连接资源监控逻辑每隔10秒读取一次CPU的通信诊断数据如果发现连接数超过12个就在HMI上弹窗提醒。具体做法是用RDREC指令读取CPU的诊断记录或者用GET_DIAG指令获取连接状态。这个逻辑稍微复杂但一旦加上现场调试时心里有底得多。5.3 独家避坑技巧心跳检测与自动重连PUT/GET通讯最怕的不是一直连不上而是连上了之后突然断然后程序不知道。我的做法是在OB1里加一个心跳计数器主动侧每秒钟往被动侧的一个特定地址写一个递增的数被动侧在程序里读这个数如果连续3秒没变化就认为通讯中断触发报警。同时主动侧在PUT指令的ERROR位触发时延时1秒后重新触发REQ尝试重连。这个逻辑用梯形图写起来大概十几行但效果非常好。我有个项目在化工厂电磁干扰严重网络偶尔闪断加了心跳重连之后通讯恢复时间从原来的几分钟缩短到几秒钟客户几乎感觉不到。5.4 独家避坑技巧固件版本一致性S7-1200的PUT/GET通讯对固件版本有一定要求。如果主动侧是V4.0被动侧是V4.4有时候会出现连接协商失败。我建议同一个项目里的S7-1200尽量刷成同一个固件版本。如果实在刷不了至少在TIA Portal里把两边的硬件配置都更新到最新确保GSD文件版本一致。还有一个隐藏的坑TIA Portal的版本也会影响PUT/GET的组态。V14和V15生成的连接参数在V16里打开时可能会提示“连接参数不兼容”。所以项目交接时一定要把TIA Portal的版本号写清楚避免后续维护时打不开项目。5.5 独家避坑技巧不要用PUT/GET传大量数据PUT/GET适合传少量、低频的数据比如状态字、设定值、计数。如果你要传几百个字节的配方数据或者高频采集的模拟量PUT/GET的效率很低而且容易出错。这种场景我建议用TSEND_C和TRCV_C指令基于TCP/IP做开放式通讯效率高得多而且可以自定义协议灵活性更好。我见过一个项目用PUT/GET传一个200字节的配方每次修改配方都要等好几秒而且偶尔会丢数据。后来改成TCP通讯传输时间降到几十毫秒稳定性也上去了。所以工具选型很重要PUT/GET不是万能的。6. 从项目实战中总结的几条硬经验6.1 先画地址映射表再动手不管项目大小只要涉及PUT/GET我一定先画一张地址映射表。表格里列清楚变量名、数据类型、被动侧绝对地址、主动侧映射地址、读写方向、长度。这张表不仅是组态时的依据也是后期排查问题的“地图”。有一次现场通讯故障我拿出映射表一核对发现被动侧DB块里插了一个新变量导致后面所有地址偏移了2个字节。如果没有这张表光靠在线监控可能半天都找不到原因。6.2 被动侧程序也要做数据校验虽然PUT/GET是直接写内存被动侧程序不参与但被动侧程序可以读这些数据然后做范围校验。比如主动侧写过来的Speed设定值被动侧程序可以判断是否在0-3000之间如果超出范围就强制归零并报警。这样即使主动侧程序出错写了异常值被动侧也能兜底避免设备飞车。6.3 网络质量决定通讯稳定性PUT/GET对网络质量很敏感。如果两个PLC之间的网线太长或者经过多个交换机丢包率上升通讯就会不稳定。我建议在条件允许的情况下两个PLC之间用直连网线或者用工业级交换机。如果必须经过多个节点一定要用带网管功能的交换机划分VLAN隔离广播风暴。还有一点S7-1200的PROFINET接口是百兆的如果你用的交换机是千兆的有时候会出现协商问题。我遇到过用千兆交换机时PUT/GET频繁断线换成百兆交换机就稳定了。后来查资料发现是S7-1200的PHY芯片对千兆协商支持不好虽然理论上兼容但实际用起来就是有问题。所以交换机不一定要追求高速匹配才是关键。6.4 文档和注释比程序本身更重要PLC程序有个特点写的时候自己看得懂过半年再看就跟天书一样。PUT/GET这种涉及跨PLC地址映射的程序更是如此。我的习惯是每个PUT/GET指令上面都加一段注释写明“从PLC_2的DB2.DBX0.0读20字节到PLC_1的DB1.DBX0.0对应Speed、Status、Count、Buffer”。然后在DB块里每个变量后面也加注释写明绝对地址和用途。这样即使项目交接给别人别人也能很快上手。6.5 现场调试带齐工具最后说点实在的。调试PUT/GET通讯现场一定要带这几样东西一根靠谱的网线最好带屏蔽、一个USB转网口有些工控机没有网口、一个便携交换机、一个笔记本装好TIA Portal和Ping工具。我吃过亏有一次现场只有一根网线结果那根网线水晶头接触不良Ping时通时断折腾了两个小时才发现是线的问题。从那以后我包里永远备着两根成品网线和一盒水晶头。另外TIA Portal的在线诊断功能一定要会用。在“在线和诊断”里可以查看CPU的连接资源、通讯负载、诊断缓冲区。诊断缓冲区里的条目能直接告诉你连接是被谁断开的、什么原因断的。这个信息比看STATUS字有用得多。说到底S7-1200的PUT/GET通讯不是什么高深技术但细节特别多。每一个细节没注意到都可能变成现场的一个故障点。把上面这五个关键点吃透再结合自己的项目实际多练几遍你会发现PUT/GET其实很稳稳到你可以放心地把设备交给客户不用半夜被电话叫醒。