搞工控的人,迟早要跟S7通讯打交道。
两台PLC之间传个数据、HMI读写DB块、上位机采集生产数据——这些场景全都绕不开S7协议。
但很多人学了半天,连单边通讯和双边通讯的区别都说不清,PUT/GET的参数填错一个就报错,DB块优化访问忘关就死活读不到数据。
今天把S7通讯这件事,从头到尾讲透。
一、S7通讯到底是什么?
S7通讯是西门子PLC家族内部的"官方语言"。
不管是S7-200 SMART、S7-300、S7-1200还是S7-1500,只要是西门子的PLC,它们之间通信用的都是这套协议。
它不是一个开放协议,而是西门子专门为自家设备设计的内部通信规则,封装在ISO-on-TCP(RFC 1006)里,走的是TCP 102端口。
你可以把S7通讯理解为:
两台西门子PLC之间的一条"专线电话"。电话已经帮你接好了,你只需要往约定的位置写数据、从约定的位置读数据,对面就能收到。
二、两种通讯方式,别搞混
S7通讯分成两大类,很多人搞不清楚就瞎配:
类型 | 指令 | 特点 | 适用场景 |
| 单边通讯 | PUT / GET | 只有一方写程序,另一方啥也不用管 | 1200/1500读写对方数据,HMI采集 |
| 双边通讯 | BSEND/BRCV、USEND/URCV、TSEND/TRCV | 双方都要写程序,配合完成 | 大数据量传输、需要严格同步的场景 |
为什么大部分场景用单边通讯就够了?
因为PUT/GET只需要"主动方"写程序,被动方连程序都不用写,只要配好连接、开放PUT/GET权限就行。配置简单、调试快,是日常项目中最常用的方式。
双边通讯(BSEND/BRCV)适合传大数据(超过PUT/GET限制的240字节),或者需要发送方和接收方严格同步触发的场景。
一句话总结:
日常用PUT/GET搞定90%的场景,大数据量或严格同步才上双边。
三、PUT/GET单边通讯:最实用的方案
3.1 原理
PUT = 主动把数据"推"给对方
GET = 主动从对方那里"拉"数据
两个指令都是"单边主动"——只有调用方需要编程,对方完全被动。
3.2 管脚说明
GET指令(从对方读取数据):
管脚 | 方向 | 作用 |
REQ | 输入 | 上升沿触发一次读取(用2Hz时钟脉冲) |
ID | 输入 | 连接号,必须与连接配置中的Local ID一致 |
ADDR_1 | 输入 | 指向对方的发送数据区地址 |
SD_1 | 输入 | 指向本地的接收数据区地址 |
NDR | 输出 | 收到新数据时置1 |
ERROR | 输出 | 出错时置1 |
STATUS | 输出 | 错误代码 |
PUT指令(向对方写入数据):
管脚 | 方向 | 作用 |
REQ | 输入 | 上升沿触发一次写入(用2Hz时钟脉冲) |
ID | 输入 | 连接号,必须与连接配置中的Local ID一致 |
ADDR_1 | 输入 | 指向对方的接收数据区地址 |
SD_1 | 输入 | 指向本地的发送数据区地址 |
DONE | 输出 | 写入完成时置1 |
ERROR | 输出 | 出错时置1 |
关键区别:
GET的ADDR_1指向对方的发送区,SD_1指向本地的接收区
PUT的ADDR_1指向对方的接收区,SD_1指向本地的发送区
搞反了就读不到、写不进去。记住口诀:GET读对方的发,PUT写对方的收。
四、连接配置:三步不能错
不管是单边还是双边,S7通讯的前提都是先把连接建起来。
以博途(TIA Portal)为例,配置S7连接的核心步骤:
第一步:网络视图中建连接
打开"设备和网络"→ 切换到"网络视图"
点击左上角"连接"图标,进入连接模式
下拉框选择"S7连接"
从主动方CPU拖到被动方CPU,松开鼠标
第二步:设置连接参数
在连接表的"常规"选项卡中:
参数 | 说明 | 注意事项 |
| 本地ID | | 本地唯一,编程时ID管脚要填这个值 |
| 伙伴IP | 对方PLC的IP地址 | 必须与实际IP一致 |
| 主动建立连接 | 勾选=主动方,不勾=被动方 | 单边通讯时只有一方勾选 |
| 特殊连接属性 | 允许主动建立连接+主动发送和接收 | PUT/GET必须勾选这两项 |
第三步:两边都下载硬件组态
配置完编译保存,下载到PLC。连接成功后,连接表里的状态图标会变成绿色。
最常见的三个低级错误:
Local ID填错了
→ 编程时ID管脚的值必须跟连接配置里一模一样
被动方没开PUT/GET权限
→ 在CPU属性→保护与安全→连接机制中,勾选"允许来自远程伙伴的PUT/GET通信访问"
IP地址写错了
→ 检查一下,别笑,真有人犯
五、DB块配置:最容易踩的坑
S7通讯传数据用的是DB块,但DB块有个默认设置会让S7通讯直接失败:
️ 必须关闭"优化的块访问"
博途新建DB块时,默认勾选"优化的块访问"。这种DB块用符号地址访问,S7通讯协议不认识。
必须手动取消勾选,改为标准访问方式。
操作步骤:
右键DB块 → 属性 → 常规 → 属性
取消勾选
"优化的块访问"
点击确定
数据区怎么定义?
关闭优化访问后,DB块就变成了标准的字节数组:
为什么必须用标准访问?
因为S7通讯协议底层是按"DB块号.字节偏移量"来寻址的。优化访问的DB块没有这个物理地址映射,协议根本找不到数据在哪
一句话:S7通讯的DB块,必须关优化、用字节数组。
六、地址格式:每个字节都有编号
S7通讯中,数据的定位方式是"区域 + 偏移量",必须搞清楚:
6.1 区域代码区域STEP7表示区域代码(Hex)说明输入I, IB, IW0x81物理输入点输出Q, QB, QW0x82物理输出点位存储M, MB, MW0x83内部标志位数据块DB, DBB, DBW0x84用户数据区(最常用)
6.2 地址表示法写法含义DB1.DBX0.0DB1的第0字节第0位(一个Bool)DB1.DBB2DB1的第2字节(一个Byte)DB1.DBW4DB1的偏移4开始的2字节(一个Word/Int)DB1.DBD8DB1的偏移8开始的4字节(一个DWord/Real)
6.3 偏移量计算
偏移量 = 字节地址 × 8 + 位地址
例如:DB10.DBX3.5 的偏移量 = 3×8+5 = 29(bit)
数据类型长度速查:
数据类型 | 长度(字节) | 建议对齐 |
Bool | 1位 | 无特殊要求 |
Byte/Char | 1 | 无要求 |
Int/Word | 2 | 偶数地址 |
DInt/DWord/Real | 4 | 4的倍数地址 |
LReal | 8 | 8的倍数地址 |
String[n] | n+2 | 无要求(前2字节存长度) |
一句话总结:DB块就是字节数组,每个变量按类型占若干字节,地址必须对齐。
七、双边通讯:BSEND/BRCV
当数据量超过PUT/GET限制(每次最多240字节),或者需要双方严格同步时,上双边通讯。
7.1 BSEND/BRCV 工作原理
BSEND
(发送方):把数据发出去
BRCV
(接收方):把数据收进来
双方都要编程,而且必须配合好——BSEND发出数据后,BRCV要在对应的连接上接收。
7.2 关键参数
BSEND:
管脚 | 作用 |
REQ | 上升沿触发发送 |
ID | 连接号(与连接配置一致) |
R_ID | 功能连接号,收发双方必须匹配 |
SD_1 | 本地发送数据区 |
LEN | 发送数据长度(字节) |
DONE | 发送完成标志 |
BRCV:
管脚 | 作用 |
EN_R | 1=使能接收 |
ID | 连接号 |
R_ID | 功能连接号,必须与BSEND一致 |
RD_1 | 本地接收数据区 |
NDR | 收到新数据标志 |
LEN | 实际接收到的数据长度 |
7.3 连接配置的区别
双边通讯的连接配置中,连接资源必须设为10(而不是单边通讯的默认值)。
同时,双方的TSAP、机架号/插槽号都要正确填写:
伙伴的机架号(Rack)= 对方CPU所在机架
伙伴的插槽号(Slot)= 对方CPU的槽位(通常是1或2)
八、常见问题排查
现象 | 可能原因 | 解决方法 |
连接状态不绿 | IP不通、子网掩码不对 | ping一下,检查网络配置 |
PUT/GET报错8090 | 被动方没开PUT/GET权限 | CPU属性→保护→勾选"允许PUT/GET" |
读到的数据全是0 | DB块没关优化访问 | 取消勾选"优化的块访问" |
ID参数报错 | 连接号不匹配 | 核对连接配置中的Local ID |
数据错乱、字节错位 | 地址偏移量算错了 | 检查数据类型长度和对齐规则 |
BSEND/BRCV收不到 | R_ID不匹配 | 双方的R_ID必须一致 |
超过240字节PUT失败 | 超出PUT/GET单次限制 | 改用BSEND/BRCV双边通讯 |
排查顺序口诀:
先ping通、再查权限、看DB优化、对ID号、算偏移。
九、S7通讯选型决策表场景推荐方式理由两台1200/1500传少量数据PUT/GET单边配置简单,一方编程即可1200与300/400通讯PUT/GET单边兼容性好数据量>240字节BSEND/BRCV双边PUT/GET有长度限制需要严格同步触发双边通讯BSEND/BRCV有握手机制HMI读写PLC数据S7通讯(内置)HMI原生支持上位机/SCADA采集S7协议(OPC或Socket)走标准S7协议即可
总结:S7通讯学习路径
最后记住三句话:
PUT/GET是日常首选,单边编程,简单高效DB块必须关优化,否则S7协议找不到数据地址要对齐、ID要匹配、权限要开放——这三个是报错最多的原因