news 2026/10/19 11:26:20

S7-1200主从PLC通信实战:PUT/GET指令详解与配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
S7-1200主从PLC通信实战:PUT/GET指令详解与配置

一条产线上你总会遇到这种情况:三台设备各用一台 S7-1200 控制,但设备之间要联动。1 号机停了,后面两台必须跟着停;1 号机还要把配方号、运行模式同步给后面两台;每台的产量和故障状态又得汇总回中控。有人图省事,PLC 之间直接拉 IO 点做硬联锁,结果线多、故障点难查,改流程的时候更是崩溃。这种场景下,S7-1200 主从 PLC 编程就是非常实用的解法,而且它解决的问题远比“两台 PLC 连根网线”要深。

主从 PLC 并不是把一个 PLC 完全交给另一个 PLC 去管,而是通过以太网通信把数据打通:主站 PLC 定期把控制字、配方、指令写到从站的指定数据区,同时把从站的状态字、产量、报警读回来。用大白话说,就是两台 PLC 在“对话”,而背后真正干活的,是 S7 通信里 PUT 和 GET 这两条指令。本文适合正在用 S7-1200 做产线级项目的电气工程师和调试人员,哪怕你之前没碰过 PLC 间通信,照着配置也能把两台 1200 拉起来通信。

1. 主从架构的核心思路与使用场景

1.1 什么场景下需要 PLC 与 PLC 做“主从”

先说最常见的几个场景,看看你中招几个。

第一类是产线分段控制。一条装配线被分成进料段、加工段、检测段,每一段独立用一台 S7-1200 控制,但整条线又需要一个统一的启停逻辑。如果各段之间没有数据交换,就会出现“前面已经在加工了,后面段还没准备好”这种脱节。这个时候主从 PLC 架构的价值就很明显:主站统一发号施令,从站各自管好自己那一段设备。

第二类是设备间联锁。比如 1 号机是上游设备,2 号机是下游设备。1 号机仓满或者故障时,2 号机必须立刻停止进料。用硬接线做联锁也行,就是每个联锁信号都要拉一根线,穿管、接线、查错都很麻烦。而通过主从通信,你只需要在程序里做几个字节的数据映射,就把联锁关系写清楚了,后期改联锁逻辑也不用动一根线。

第三类是数据汇总与配方下发。主站需要收集各从站的产量、故障代码、运行时长,同时把配方参数下发到从站。这种数据量不大,但要是用文本协议一帧一帧地去拼,现场调试能拼到怀疑人生。用 PUT/GET 直接读写对方 DB 块,数据同步就是“一次到位”的事。

第四类是远程监控。中控室的上位机只需要连主站,其余从站的数据由主站统一采集,这样组态软件不用同时去轮询多台 PLC,网络压力小很多。这个思路在中小型项目里特别常见,既省了上位机点数,也简化了画面组态。

1.2 先分清“主从通信”和“分布式 I/O”

这里必须先掰扯清楚一个概念,否则后面很容易被误导。在 PROFINET 体系里,“主从”这个词其实有两种常见用法。

一种是 IO Controller 与 IO Device 的关系,也就是大家常说的分布式 I/O。S7-1200 做 IO Controller,下面挂 ET200SP 这类远程 IO 从站,这时候从站本质上只是远程的输入输出模块,程序还是跑在主站 PLC 里。这种方式适合设备点位多、布线不方便的场合,但“从站”本身没有独立控制能力。

另一种就是本文要展开的 PLC 与 PLC 之间的逻辑主从关系。两台或更多 S7-1200 各自运行独立的用户程序,通过以太网建立 S7 连接,主站主动读写从站的数据区。从站不是单纯的点位扩展,它有自己的控制逻辑,只是把需要交互的数据开放给主站。

两者的根本差别在于:分布式 I/O 解决的是“IO 拉线远”的问题,逻辑主从通信解决的是“多套控制系统之间数据互通”的问题。我见过有人把 ET200SP 从站挂在 1200 下面,然后说“这是主从 PLC”,严格来说不够准确。你只有真正在从站 PLC 里写了独立程序,两台 PLC 之间做数据交换,这才是 PLC 与 PLC 的主从架构。

1.3 主从架构带来的实际收益

先算一笔账。原来做 3 台设备联动,每个联锁信号拉一根线,至少 10 根以上的信号线,加上动力电缆,整个柜内接线量和现场穿管量都很可观。改了主从通信之后,三台 PLC 之间只需要一根工业以太网线,所有联锁信号都跑在数据区里。省下的不只是线缆成本,更是调试时间和排查时间。

再算可靠性。硬接线联锁最怕的就是虚接、断线,一根线松了,故障表现还特别诡异,时好时坏。而以太网通信自带 CRC 校验和重传机制,通信质量稳定得多。当然通信也有通信的问题,比如断线后数据不更新,这就要靠后面讲的心跳机制来处理。

还有一点容易被忽略:主从架构天然支持扩展。哪天产线加一段设备,只要给新设备配一台 PLC,组态一个网络连接,在主站数据区里多映射几个字,就能接入整个系统。硬接线方案想加联锁?先把柜子拆开再说。

2. 通信方案选型:PUT/GET、TCP、Modbus TCP 怎么选

2.1 三种主流通信方式对比

S7-1200 之间做数据交换,常见的无非三条路:S7 通信(PUT/GET)、开放式 TCP 通信(TCON/TSEND/TRCV)、Modbus TCP。

先说 PUT/GET。它是西门子 S7 系列的老牌通信方式,直接读写对方的 DB 块、M 区,不需要双方约定复杂的报文格式。编程时有专门的指令,填参数就行,最重要的是它天然支持“按地址访问对方数据区”这个语义,非常适合做主从数据交换。

再说开放式 TCP。通过 TCON、TSEND、TRCV 自己发起 TCP 连接,自己定义收发缓冲区,想传什么、什么时候传,都由你的程序说了算。灵活性最高,但编程量也最大。你得自己处理连接建立、断线重连、报文拆包粘包、超时判断,一个环节考虑不到,现场就给你颜色看。

还有 Modbus TCP。这是跨品牌通信的“万金油”,很多第三方仪表、驱动器、触摸屏都支持。S7-1200 可以用 MB_CLIENT 和 MB_SERVER 指令实现。它最大的好处是协议公开、通用性强,缺点是数据地址按 Modbus 协议组织,没有西门子自己的数据区那么直观,而且主站轮询从站时,要自己管理功能码和数据映射。

通信方式编程难度跨品牌能力数据实时性适用场景
PUT/GET低仅西门子毫秒级,较高西门子 PLC 之间主从数据交换
开放式 TCP高强取决于编程与上位机、视觉、机器人等第三方系统通信
Modbus TCP中强中跨品牌设备或仪表数据采集

2.2 为什么 S7-1200 之间我首选 PUT/GET

如果通信双方都是 S7-1200,我几乎不会犹豫,直接选 PUT/GET。原因是这个方案把“连接管理”和“数据访问”两件事都替你封装好了。

你想想,开放式 TCP 通信里面,你先要建立一个连接,然后约定报文头、长度、校验,还要考虑对方什么时候发数据、一次发多少个字节。而 PUT/GET 的逻辑很简单:写就是把本地数据区搬过去,读就是把对方数据区搬回来。哪怕是一个刚接触通信的新手,只要理解“发送区”和“接收区”两个概念,就能把程序写出来。

从维护角度讲,PUT/GET 的程序可读性也最好。打开程序,看到 GET 指令的地址填的是“DB300.DBX0.0 BYTE 20”,你一眼就知道从站哪个数据块的第几个字节被读回来了。这比去解析一段 TCP 报文缓冲区里的第 4 个字节是什么含义要直观得多。

还有一个工程上的实际原因:S7-1200 自带诊断功能,PUT/GET 指令执行出错时,STATUS 引脚会给出错误代码,配合 TIA 在线诊断和 CPU 诊断缓冲区,排查问题要比自己实现 TCP 协议简单得多。你自己写的 TCP 通信程序出问题,只能靠抓包,现场可未必方便抓包。

2.3 什么时候别用 PUT/GET

PUT/GET 也不是万能的。如果你有下面这几种需求,就得考虑换方案。

一是通信对方不是西门子 PLC。比如产线上用的是某国产品牌 PLC,或者设备供应商用的是三菱、欧姆龙,PUT/GET 就没有用武之地了。这种情况下要么走 Modbus TCP,要么走开放式 TCP,具体看对方支持什么协议。

二是要大数据量、高频率传输。虽然 S7-1200 的 PUT/GET 也能传几 K 字节的数据,但单个连接的 PDU 大小和 CPU 通信负载都有上限,而且通信处理会占用 CPU 扫描时间。如果你要每 10ms 同步一次几百字节的数据,用 S7-1200 做这种任务本来就吃力,不如考虑换更高级的 CPU,或者把数据做本地缓存、异步传输。

三是需要主动上报的场景。PUT/GET 本质上是主站主动读写,从站没有“主动往主站塞数据”的能力。如果从站某个事件突发,要立刻通知主站,你也得靠主站快速循环去轮询。这个模型本身就决定了从站只能“被访问”,不能“主动上报”。实在要主动上报,还是走开放式 TCP 更合适。

3. 硬件组态与基础通信配置一步步来

3.1 IP 地址规划与组态前准备

动手写程序之前,先把网络拓扑画清楚。拿最常见的两台 S7-1200 主从通信举例,主站 CPU 用的是 S7-1214C DC/DC/DC,从站也是同型号,中间接一台工业交换机。

IP 地址规划要遵循几条原则:主站、从站必须在同一网段,比如主站设 192.168.0.1,从站设 192.168.0.2,子网掩码 255.255.255.0。不能用 DHCP 默认获取,PLC 这种现场设备必须用固定 IP。还有一点容易被忽略,就是工业交换机的端口配置。简单场景下一台非网管交换机就够了,不需要做 VLAN 和端口映射,但如果是带网管的交换机,要确认端口没有隔离策略,否则 PLC 之间物理上通了、逻辑上却是隔离的。

组态前还要检查两件事。一是 CPU 固件版本,建议从站固件在 V4.0 以上,协议兼容性更好;二是 TIA Portal 的版本,至少 V13 SP1,现在 V15、V16 都很成熟,用新版本问题不大。具体做法是:打开 TIA,新建项目,添加两台 S7-1200 PLC,分别分配好 IP 地址和设备名称。设备名称在 PROFINET 里很重要,如果你后面要用在线访问或 HMI 连接,设备名称最好见名知义,比如 PLC_MASTER 和 PLC_SLAVE_1。

3.2 在 TIA 中创建 S7 连接

这是 PUT/GET 通信能不能建立起来的关键一步,也是很多人第一次做通信卡住的地方。

打开 TIA Portal,在项目树里进入“网络视图”。你会看到两台 PLC 的图标,用鼠标拖拽连接线,从主站拖到从站。弹出来的对话框里选择 S7 连接,点击确定。这时候 TIA 会为两台 PLC 建立一个 S7 连接,连接表里能看到一个条目。

双击这个连接条目,打开属性窗口,重点看“常规”选项卡里的“本地 ID”和“伙伴”配置。本地 ID 默认是十六进制的 16#0100,这个值后面编程时要填到 PUT/GET 指令的 ID 引脚上。连接方向选择“建立主动连接”,意思是主站在启动时主动去连从站,从站被动等待。如果勾反了,通信也能建立,但逻辑上不符合“主站主动”的习惯,调试时容易绕晕。

还有一个细节:在连接属性里指定伙伴接口和伙伴 IP 地址,必须与从站网口实际配置一致。我见过有人在网络视图里连接建立正常,但因为从站 IP 后来被改过,连接属性里的地址没同步更新,导致在线时连接一直起不来。所以每次改 IP 之后,都要回连接属性里检查一遍,这种低级错误一次就能消耗半天。

3.3 从站允许 PUT/GET 访问的设置

组态完连接还不行,从站那边还要开一个“门闩”。这是新手最容易漏的一步。

选中从站 CPU,双击打开属性,找到“保护与安全”选项卡,再进入“连接机制”,勾选“允许从远程伙伴进行 GET/PUT 通信访问”。这个选项如果没勾上,主站的 PUT/GET 指令会一直报错,连接建立不了,或者发过去的数据没有回应。

需要说明的是,这个开关从 V4.0 固件开始是默认开启的,老固件上则默认关闭。如果你手里的 CPU 固件版本比较旧,或者项目是从旧设备复制的,必须手动确认这个勾选状态。现场很多通信问题的根因就在这,但恰恰因为太简单,反而最容易被忽略。

从站侧还有一个安全设定值得注意:如果数据区只是给主站读取,不想让主站写入,可以在 DB 块属性里设置访问权限。比如把心率、状态字这些只允许主站读的 DB 设成“仅读”,主站 GET 没问题,PUT 写这个区就会被拒绝。这个机制能在通信层面对协作双方的数据做最基础的隔离,多花一分钟配置,能少很多现场扯皮。

3.4 DB 块优化访问与标准访问

接下来是 PUT/GET 编程里最核心的坑:DB 块的访问类型。

TIA Portal 从博途 V13 开始,新建的 DB 块默认是“优化的块访问”。优化后的 DB 块不再有传统的物理地址,系统自己管理符号寻址,访问速度更快,安全性也更好。但问题来了:PUT/GET 指令要访问对方 DB 块时,偏偏需要的是传统意义的绝对物理地址。如果从站的 DB 块保留了优化访问属性,主站的 PUT/GET 在寻址时会找不到目标地址,通信直接失败。

解决办法有两个。一种是在从站侧把目标 DB 块属性里的“优化的块访问”取消勾选,这样这个 DB 块就变成标准访问,会看到偏移地址,比如 DB300.DBX0.0 这种形式。另一种是新建一个专门用于通信的 DB 块,创建时就取消优化访问,专门开放给主站读写。

我的习惯是单独建通信 DB,而不是把自己程序里的核心 DB 直接暴露给主站。原因很简单:程序内部 DB 的结构会随着功能迭代频繁变动,一旦开放给主站通信,改结构就得同步改主站地址,搞不好就把别人那边的数据弄错了。而通信 DB 的结构基本固定,里面的每个字节是干什么的都有详细注释,主从双方都按这个契约来,后期维护省心太多。

4. 核心编程实操:PUT/GET 指令详解与程序框架

4.1 PUT 和 GET 到底在做什么

从名字就能看出方向。PUT 是主站往从站写数据,GET 是主站从从站读数据。二者都通过 S7 连接传输,传输的内容是你指定的一段连续地址空间,可以是字节、字或更大的数据块。

在脑海里建立这样一个模型:主站有一块“发送区”,从站有一块“接收区”,PUT 指令生命周期内,主站发送区的数据被整体搬到了从站的接收区;反过来,从站有一块“上报区”,主站有一块“接收区”,GET 指令把从站上报区的数据搬回主站接收区。理解这一步,后面填参数时就心里有数了:所有地址都是“本地某区对远端某区”的映射关系,长度必须一致。

4.2 PUT 指令的六个核心参数

在 TIA 的指令列表里找到“通信 → S7 通信 → PUT”,拖到程序段里,你会看到一堆引脚。真正每次都要仔细填的是下面这几个。

REQ:触发请求。这个引脚需要给一个上升沿或者一个周期为 TRUE 的信号,PLC 检测到之后执行一次发送。注意 REQ 不需要一直保持 TRUE,给一个脉冲合适,这样通信不需要每个扫描周期都占用 CPU。

ID:连接 ID。填网络视图里 S7 连接的本地 ID,通常就是那个 16#0100。这里最容易出的错是,一个项目里有多个 S7 连接时,指令里填的 ID 对不上,结果指令拿着半路开车的 ID 去找连接,自然找不到伙伴。

ADDR_1:从站侧数据地址。这里填的是远端从站要写入的那段地址。比如从站的通信 DB 是 DB300,数据从第 0 个字节开始,长度 20 个字节,那这里就填 DB300.DBX0.0,长度选 20。注意从站的 DB 必须是标准访问。

SD_1:主站本地发送区地址。这是主站自己的 DB 块,比如主站通信 DB 是 DB100,数据从 DBW0 开始,长度同样 20 个字节。PUT 指令会把 DB100 里这 20 个字节原封不动搬到从站的 DB300 里。

DONE / ERROR / STATUS:完成位、错误位、状态字。这是调试时最重要的信息源。DONE 为 TRUE 说明这次发送成功;ERROR 为 TRUE 说明出错,同时 STATUS 里给出错误代码。我建议每个 PUT 指令都引出这三个引脚到独立的 M 点或 DB 位里,方便在线监控,也方便后续用它们做触发逻辑。

4.3 GET 指令的核心参数

GET 指令的参数和 PUT 几乎一一对应,只是方向反过来。

REQ 和 ID 的含义与 PUT 完全一致,这里不重复。ADDR_1 填从站的数据地址,也就是从站“上报区”的起始位置,比如 DB300.DBX20.0 BYTE 20。RD_1 填主站本地接收区,比如主站通信 DB 的 DBW20 开始,长度 20 个字节。GET 执行一次,从站 DB300 从第 20 字节开始的 20 个字节,就会被搬到主站 DB100 的 DBW20 这个位置。

这里有一个工程上的重要习惯:ADDR 和 RD 指定的数据长度必须完全一致,否则指令会报错,或者只传输部分数据。长度不一致的现场表现很诡异,有时候能通,但数据不完整,排查半天发现是一个 20 一个 32,这种低级错误真的很常见。

4.4 触发方式:别每个扫描周期都发

新手最容易犯的错,就是把 REQ 直接接一个常 1 信号。这样每个扫描周期都在执行 PUT/GET,通信负载会高得离谱,CPU 扫描周期被拖慢,甚至从站响应不过来,通信质量反而下降。

正确的做法是用一个周期脉冲或者定时触发。比如建立一个 100ms 的定时器,输出接到一个 M 点上,然后用这个 M 点作为 REQ 信号。实测下来,大部分产线设备之间的联锁和状态同步,100ms 的刷新时间已经足够。如果你需要更快的实时性,可以缩到 50ms,但再快就要注意 CPU 负载了。

还有一种更好的做法是“完成一次再触发下一次”,用 DONE 和 ERROR 做成一个握手逻辑。大致思路是:只有当上一次 PUT 或 GET 完成(或者出错)之后,才允许下一次 REQ 为 TRUE。这样通信每隔固定的周期自动进行,又不会因为上一个请求还挂着就重复发起。用大白话说,就是“一趟车到站了,下一趟才发车”,整个过程非常平稳。

// 伪代码示意:完成后再触发 IF #put_done OR #put_error THEN #put_req := FALSE; END_IF; IF #cycle_trigger AND NOT #put_req THEN #put_req := TRUE; END_IF; "PUT"( REQ := #put_req, ID := 16#0100, ADDR_1 := "从站通信DB".DBX0.0 BYTE 20, SD_1 := "主站通信DB".DBX0.0 BYTE 20, DONE => #put_done, ERROR => #put_error, STATUS => #put_status );

4.5 数据区划分原则

通信数据区不是随便划的,划得不好,后期扩展就是想改哪块改哪块,结果改完发现两边对不上。我的划分原则就三条:方向明确、语义固定、长度对齐。

方向明确的意思是,同一段数据只允许单向流动。比如主站到从站的控制区是 DB100.DBW0 到 DBW10,从站到主站的状态区是 DB100.DBW20 到 DBW40,这两段绝不交叉。如果一段数据一会主站写、一会从站写,调试时两边程序都在改,最后都不知道是谁把数据改了。

语义固定就是每个地址对应什么含义要写清楚。我习惯做一个数据映射表,放在项目注释里,把每个字节的字节偏移、数据类型、含义、读写方向都列出来。这个表既是自己的设计文档,也是和同事协作的契约。有这张表在,哪怕过了半年再回头维护,也能很快找回状态。

长度对齐是指主从两侧对应区域的长度始终一致,而且预留冗余。比如现在只需要 20 个字节,我往往预留 32 个字节,多余的留空。这样将来往数据区里加一个命令字或者加一个故障编号,不用动连接配置和指令参数,只要两边都把预留区用起来就行。

5. 完整应用案例:多段装配线的数据交换与联锁

5.1 项目背景与数据映射表

用一个典型的装配线案例把前面的内容串起来。假设某装配车间有一条三段式装配线:进料段、装配段、检测段。进料段主站是一台 S7-1214C,装配段和检测段各有一台从站 1214C。三台 PLC 通过工业交换机组成同一网段。

主站需要做的事:把配方号、启动命令、停止命令下发给两个从站;读取两个从站的运行状态、故障代码、循环计数;检测段如果不良率超限,主站要能自动停掉进料段,实现联锁保护。

我把数据映射表先列出来,这是整个项目里最关键的设计环节:

主站数据区数据类型含义流向
DB100.DBW0Int配方号主站 → 从站
DB100.DBW2Int启动命令主站 → 从站
DB100.DBW4Int停止命令主站 → 从站
DB100.DBW6Int主站心跳计数主站 → 从站
DB100.DBW20Int装配段状态字从站 → 主站
DB100.DBW22Int装配段循环计数从站 → 主站
DB100.DBW24Int装配段运行时长从站 → 主站
DB100.DBW26Int装配段心跳计数从站 → 主站
DB100.DBW30Int检测段状态字从站 → 主站
DB100.DBW32Int检测段良品数从站 → 主站
DB100.DBW34Int检测段不良品数从站 → 主站
DB100.DBW36Int检测段心跳计数从站 → 主站

每个从站侧对应一个通信 DB。装配段的通信 DB 是 DB300,检测段的通信 DB 是 DB400。两个 DB 结构完全一样,都分成三块区:接收区存放主站下发命令,上报区存放本段状态,心跳区存放心跳计数。这样做的好处是同样的程序逻辑可以复制使用,从站程序只改 DB 编号,其他完全照搬。

5.2 主站程序怎么组织

主站程序分成三个模块来写:第一个模块是“发送区填充”,把要下发的命令字、配方号写入主站 DB100 的发送区;第二个模块是“通信执行”,也就是调用 PUT 和 GET 指令;第三个模块是“联锁处理”,根据读回来的从站状态字做联锁判断。

发送区填充这个模块很简单,梯形图里用 MOVE 指令,把 HMI 上设置的配方号移动到 DB100.DBW0,把启动按钮状态移动到 DB100.DBW2,停止按钮状态移到 DB100.DBW4。同时每 100ms 让主站心跳计数加 1,存到 DB100.DBW6。

联锁处理逻辑稍微有点含量。比如我读回装配段状态字 DB100.DBW20,它的 bit0 是运行位、bit1 是故障位、bit2 是急停位。主站判断规则是:如果装配段故障位为 TRUE,则立即停掉进料段,并且弹出一个报警。这个判断完全基于 PUT/GET 读回来的数据,没有一根硬接线。

5.3 通信调用的完整展示

主站程序里,对装配段的调用如下所示。注意我这里用梯形图填参的方式描述,你可以在 TIA 里对照输入:

首先是 PUT 指令,作用是给装配段下发命令。REQ 接一个 100ms 脉冲 M0.3,ID 填 16#0100,ADDR_1 填 DB300.DBX0.0 BYTE 8(装配段的接收区长度 8 个字节),SD_1 填 DB100.DBX0.0 BYTE 8(主站发送区长度 8 个字节)。DONE 接 M0.4,ERROR 接 M0.5,STATUS 接到 MW10。

然后是 GET 指令,作用是读取装配段状态。REQ 接同一个 100ms 脉冲 M0.3,ID 还是 16#0100,ADDR_1 填 DB300.DBX8.0 BYTE 8(装配段上报区起始偏移 8),RD_1 填 DB100.DBX20.0 BYTE 8(主站接收区从 DBW20 开始)。DONE 接 M1.4,ERROR 接 M1.5,STATUS 接到 MW12。

这里有一个细节值得提示:PUT 和 GET 的 REQ 触发我用的是同一个脉冲源。这种情况下一次扫描周期内会同时发起写和读两个请求,能保证数据同步性更好。如果用的是“完成再触发”逻辑,写入和读取会有半个周期的时间差,但对于 100ms 级别的刷新来说,差异完全可接受。

5.4 心跳超时与断线安全

通信最怕什么?断线后数据不更新,但程序还在按旧数据执行联锁。比如装配段已经急停了,通信断了之后主站没收到新的故障位,还在继续往下游供料。这个问题必须在程序里做一层保护。

心跳机制是标准的解法。每个从站程序里维护一个心跳计数,每秒加一次,存在通信 DB 的心跳区里。主站每次 GET 把心跳值读回来,和上一次做比较。如果连续几个周期心跳值都没变化,就认为这个从站的通信链路异常。

主站程序里做一个心跳超时判断:把从站心跳计数用减法指令和上一次值做比较,差值保持不变就加一个超时计数,超过比如 5 次就置位通信超时位。通信超时之后,主站进入“安全状态”,比如停止进料段运行、禁止下发新配方,同时在 HMI 上显示“通信中断”报警。

注意,这里的安全状态只是主站侧的自我保护。务必记住,从站自身必须有独立的安全停机逻辑。不能依赖主站的保护,因为通信断了主站未必能及时把停机命令送过来。从站的程序里要自己判断运行条件,比如进料段没有准备好就绝对不允许启动,把安全底线放在本地逻辑里。我经常说,通信是用来协作的,不是用来保命的,安全功能永远要落在现场那一侧。

5.5 从站侧程序要点

从站程序相对简单,核心是把自己的状态写成数据、把主站命令读出来用。

从站的通信 DB 接收区就是 DB300.DBW0 到 DBW6。装配段程序里要把启动命令和停止命令从这个区域读出来,转成内部中间变量。比如 DB300.DBW2 为 1 时,置位自己的启动中间位,这个中间位再去控制实际的输出。这样做的目的是把通信数据和逻辑控制做了解耦,防止主站那边数据乱写或者通信抖动时,直接干扰到从站设备。

从站每隔一秒把自身的状态字和循环计数写入上报区。状态字需要自己拼。比如 bit0 是运行状态,bit1 是故障状态,bit2 是急停状态,就用赋值指令把几个位组合成一个整数之后写进 DB300.DBW8。

从站还要把心跳计数(DB300.DBW14)每秒加一次。这个从站侧的心跳非常重要,因为如果从站程序死机或者扫描周期异常,主站也能通过心跳发现从站“不在线”了。

6. 常见问题与排查技巧实录

6.1 通信建立不起来?按这四步查

现场调试时通信起不来,先别急着翻程序。我的固定套路是四步走,按顺序排查,八成问题都能解决。

第一步查 IP。确认主站、从站的 IP 在同一网段,并且和编程电脑不冲突。用笔记本电脑手动配好 IP,直接 ping 从站地址,不通就查网线、网口、交换机,物理层通了再说别的。

第二步查连接。确认网络视图里 S7 连接已经建立,并且本地 ID 填到了指令里。这里最容易出问题的是指令 ID 和连接 ID 不一致,尤其是项目里存在多个连接时。

第三步查从站安全设置。确认从站 CPU 属性的“允许从远程伙伴进行 GET/PUT 通信访问”已勾选。这一步是权限层的开关,没开的话连接建立都可能被拒。

第四步查 DB 块访问类型。确认从站通信 DB 块不是“优化的块访问”。这个属性在 DB 块属性里,取消勾选后重新编译下载。

6.2 DONE 不置位,STATUS 报错怎么定位

通信正常时,每次 REQ 触发后 DONE 会跟着置位,表示本次传输完成。但如果 REQ 给了,DONE 一直不亮,ERROR 反而偶尔闪一下,这就说明有问题。

首先把 STATUS 的值记下来,在 TIA 在线诊断里选择对应的 CPU,看诊断缓冲区有没有相关条目。S7 通信的错误代码比较直白,常出现的几类都是配置层面:连接 ID 无效、伙伴拒绝访问、目标地址不存在或长度越界。这几个方向分别对应前面第 3 节的几个配置点,逐一核对。

有一个独特的排查技巧:把 GET 的 ADDR_1 长度先改成 2 个字节试试。如果 2 个字节能通,20 个字节不通,基本就是地址范围或者长度对齐的问题。这种“缩小范围试通法”在现场非常高效,要比光看错误码猜快得多。

6.3 读得到写不进,多半是 DB 块属性

这个现象很有代表性,GET 能正常读回数据,但 PUT 死活写不进去,从站的数据区一点变化都没有。排除了连接和权限问题之后,九成原因是目标 DB 块的写权限。

打开从站通信 DB 的属性,在“访问权限”里看是不是设置了“仅读”。如果 DB 设成只读,主站 GET 不影响,PUT 就会失败。还有一个可能是这个 DB 被从站程序里其他指令占用了,比如某个脉冲一直在给 DB300.DBW0 赋值,主站刚写过去的配方号,下一秒就被从站程序覆盖了。这种情况要梳理从站程序,同一块数据只允许单方向写。

6.4 数据偶尔乱一下,怎么处理

如果通信正常,但监控画面里的数据偶尔闪一个错误数值,尤其是运行计数这类数值,多半是读数时序问题。比如从站正在把计数从 999 加到 1000,主站在这个瞬间 GET 了半个过程的数据,导致读到的是 999 和 1000 的混合值。

解决办法之一,是从站侧把需要一致传输的数据集中在一段连续的地址区里,并且通过“先更新数据、再更新心跳”的方式让主站判断数据的完整性。主站看到心跳变了,才认为本批次数据有效。

更简单粗暴的解法,是把数据从 Int 放大到 DWord,或者把大整数拆成多个字触发。但我不建议过度设计,产线常规数据交换的场景下,偶尔一次跳动造成的后果大多可控,关键是把报警阈值和联锁逻辑做好滤波。

6.5 通信负载过高,CPU 扫描时间变长

有的项目改完通信之后,发现 PLC 扫描周期从原来的 5ms 涨到 30ms 甚至更高。这是典型的通信负载超标。

先把你 REQ 的触发频率降下来。100ms 触发一次就够了,不要 5ms 触发。然后把不必要的读取减掉,比如状态字 1 秒刷新一次即可,不需要 100ms 一次。最后检查一下是不是同一个 CPU 上挂了太多 S7 连接和数据量,如果资源确实不够,就得把一部分数据交换挪到上位机或者换更强的 CPU。

这里我想多说一句,P LC 的通信资源是固定的,S7-1200 虽然能同时建立多个连接,但每个连接都占缓冲区、CPU 时间。好的程序框架应该让通信“低频、小包、连续”,而不是“高频、大包、突发”。现场调试时,我一个人把触发周期从 20ms 放大到 200ms,扫描周期立刻从 20ms 掉回 5ms,而且设备联动根本感觉不到差别。这点经验相当重要。

7. 最后再分享几个调试细节

说实话这套通信并不复杂,但工程上八成的问题都出在配置细节上。只要你把 IP、S7 连接、从站访问许可、DB 优化访问这四个点抓好,一套主从 PLC 通信基本就是半小时的事。我个人的习惯是,在做完通信配置之后,先不开任何业务逻辑,单独写一个测试程序,让主站往从站写一个数、从站往主站回一个数,两边通了再往上叠逻辑。这样后面排查问题的时候,至少能确认底层通信是好的。

还有一个小技巧,就是每次修改从站通信 DB 的地址映射后,记得把主站程序里的 ADDR 和 SD 长度重新核对一遍。两边数据表的长度不一致,指令不报错,但数据就是不对,这种坑特别隐蔽。用你自己做的数据映射表逐项对一次,比现场试错快得多。

这套主从通信方案我在多个项目里都用了,从两台的简单联动到七八台的中等规模产线,都很稳定。你只要把基础配置吃透,后续扩展无非是多建几个 S7 连接、多调几组 PUT/GET,思路完全一致。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 11:25:50

安全代理域名如何被钓鱼攻击滥用?信任链检测与防御实战

最近在复盘一批钓鱼样本时,有个现象特别值得拿出来说。攻击者越来越不爱用那种一看就很假的仿冒域名了,反而开始盯上那些带着“安全”字眼、经过合法代理机制包装的域名,专门吃用户和检测系统对“安全域名”的信任。这种攻击模型,…

作者头像 李华
网站建设 2026/10/19 11:25:48

MySQL外键约束失败排查:从字符集到级联的完整定位指南

这个报错大概是MySQL开发中出镜率最高的外键错误之一,报错信息就一句话,但背后的触发原因五花八门。有时候你查了半天数据,发现子表里确实没有那条记录,父表里也确实有对应的主键,但SQL就是执行失败。这篇博文我不打算…

作者头像 李华
网站建设 2026/10/19 11:24:44

MySQL Errcode 13排查:从权限到secure_file_priv的完整指南

那天晚上我正在给一张订单流水表做离线对账,表里攒了四千多万行数据,直接 SELECT ... INTO OUTFILE 导出成 CSV 是最省事的方案。结果定时任务日志里出现了一段让我有点来火的报错: ERROR 1 (HY000) at line 1: Cant create/write to fil…

作者头像 李华
网站建设 2026/10/19 11:24:28

Windows内核I2C驱动开发:KMDF+SPB+ACPI教学闭环

简介:本资源是一套面向嵌入式与Windows内核开发初学者的实践型源码项目,聚焦I2C设备在Windows平台下的全栈通信实现,适用于高校电子/计算机专业学生、驱动开发入门者及对KMDF和SPB总线机制感兴趣的工程师。项目完整覆盖用户态WinRT API调用、…

作者头像 李华
网站建设 2026/10/19 11:24:10

OSPF网络类型全解析:从原理到排障,一篇掌握五种类型

搞网络这一行,只要绕不开OSPF,就绕不开网络类型这四个字。我前阵子帮人排查一个邻居起不来的问题,折腾到后半夜,根因就是接口上的OSPF网络类型两端设置不一致。OSPF网络类型决定了Hello报文用什么方式发出去、要不要选DR/BDR、邻居…

作者头像 李华
网站建设 2026/10/19 11:24:00

基于Spring Boot的车辆综合服务平台开发实战:从需求拆分到落地部署

大学毕业设计做了一圈管理系统,唯独车辆相关的项目特别多,但大多数质量堪忧。前阵子帮朋友梳理一个基于Spring Boot的车辆综合服务平台,从需求拆分到落地部署完整走了一遍,发现这类项目真正难的不是CRUD,而是业务边界、…

作者头像 李华