跳到主要内容

西门子 S7 协议通讯

Darra PLC 支持与西门子 S7 系列 PLC 的通讯, 基于成熟的工业通讯协议库实现。

支持型号

系列型号连接方式说明
S7-200CPU 22xPPI/以太网通过 Smart 模块
S7-200 SmartCPU SR/ST以太网直连
S7-300CPU 31x/31xC以太网MPI/PROFINET
S7-400CPU 41x以太网机架号+槽号
S7-1200CPU 121x以太网需关闭优化块访问
S7-1500CPU 151x以太网需关闭优化块访问
S7-1200/1500 注意事项

S7-1200 和 S7-1500 需要在 TIA Portal 中进行以下设置:

  1. DB 块属性中取消勾选"优化的块访问"
  2. 在 CPU 属性 → 防护与安全中, 允许来自远程对象的 PUT/GET 通讯

存储区访问

存储区标识地址示例说明
I 输入映像II0.0, IB0, IW0输入过程映像
Q 输出映像QQ0.0, QB0, QW0输出过程映像
M 标志区MM0.0, MB0, MW0, MD0内部标志
DB 数据块DBDB1.DBX0.0, DB1.DBW0数据块
T 定时器TT0定时器当前值
C 计数器CC0计数器当前值

连接配置

{
"protocol": "S7",
"host": "192.168.1.10",
"port": 102,
"rack": 0,
"slot": 1,
"plcType": "S7-1500",
"timeout": 3000
}

槽号参考:

  • S7-300: Rack=0, Slot=2
  • S7-400: Rack=0, Slot=3 (或实际槽号)
  • S7-1200/1500: Rack=0, Slot=0 或 1

PLC 变量映射

将西门子 PLC 的数据映射到 Darra PLC 变量:

西门子 S7 地址          Darra PLC 变量
DB1.DBW0 ←→ MW1000 (INT)
DB1.DBD4 ←→ MD1004 (REAL)
DB1.DBX8.0 ←→ MX1008.0 (BOOL)
I0.0 ←→ IX0.0 (BOOL, 只读)
Q0.0 ←→ QX0.0 (BOOL)

代码示例

// 创建 S7 连接
var adapter = PLCDriverFactory.Create(ProtocolId.SiemensS7);
await adapter.ConnectAsync(new ConnectionConfig
{
Host = "192.168.1.10",
Port = 102,
Rack = 0,
Slot = 1,
PlcType = S7PlcType.S71500
});

// 读取 DB1.DBW0 (INT16)
var data = await adapter.ReadAsync("DB1.DBW0", 2);
short value = BitConverter.ToInt16(data, 0);

// 写入 DB1.DBD4 (REAL)
await adapter.WriteAsync("DB1.DBD4", BitConverter.GetBytes(3.14f));
批量读写

建议使用批量读写减少通讯次数。一次最多读取 200 个字节, 多个不连续地址会自动优化合并。

S7 协议背景

S7 是西门子自有的 PLC 通讯协议, 也称为 ISO-on-TCP / S7comm。它跑在 TCP 端口 102 上, 底层用 ISO 8073 / RFC 1006 包装:

应用层:    S7 PDU
会话层: COTP (ISO 8073)
传输层: TPKT (RFC 1006)
网络层: TCP (Port 102)

Darra 的 S7 适配器参考 HslCommunication 和 Snap7 等公开实现, 不调用西门子官方库。

PUT/GET 权限设置

S7-1200/1500 默认禁止外部 PUT/GET:

  1. TIA Portal 中选中 CPU → 属性 → 防护与安全 → 连接机制
  2. 勾选 "允许来自远程伙伴的 PUT/GET 通信访问"
  3. 重新下载 CPU 配置

如果不开启, 适配器会在连接阶段收到 S7 Error 0x81 认证失败, 日志里会有提示。

优化块访问

S7-1200/1500 的 DB 块有两种访问模式:

模式外部可读写内存布局
优化的块访问 (默认)需要按符号名 (不推荐)连续优化
标准的块访问按地址偏移 (Darra 用这个)固定偏移

取消优化 方法:

  1. 在 DB 块上右键 → 属性 → 属性 → 取消勾选"优化的块访问"
  2. 保存, 重新编译 CPU
  3. 下载到 PLC

取消后可以通过 DB1.DBW0 这样的绝对地址访问。不取消的话只能用 S7-TIA 原生接口 (不支持跨厂商)。

地址语法

Darra 支持的 S7 地址语法:

格式说明示例
I<b>.<b>输入位I0.0
IB<n> / IW<n> / ID<n>输入字节/字/双字IW4
Q<b>.<b> / QB/QW/QD输出Q2.1
M<b>.<b> / MB/MW/MD标志MD20
DB<n>.DBX<b>.<b>DB 位DB1.DBX0.0
DB<n>.DBB<b> / DBW / DBDDB 字节/字/双字DB1.DBW10
T<n>定时器 (S7-300/400)T3
C<n>计数器 (S7-300/400)C5

S7-1200/1500 的时间型变量推荐用 DB 里的 TIME 类型, 避免使用传统 T0

数据类型与字节序

S7 采用大端序 (Big-Endian), 多字节类型高位在前:

类型大小注意
BOOL1 bit位地址 .0~.7
BYTE1 B
WORD / INT2 B大端
DWORD / DINT4 B大端
REAL4 BIEEE 754 大端
LREAL8 B仅 S7-1500
STRING可变长度前缀 + 实际长度 + 字符
DT (Date_And_Time)8 BBCD 编码
S5TIME2 BS5 格式定时器

PLC 里默认 BitConverter 是小端, 读回后需 Reverse:

var data = await adapter.ReadAsync("DB1.DBD0", 4);
float value = BitConverter.ToSingle(data.Reverse().ToArray(), 0);

或者使用 SDK 提供的 ReadReal:

float value = await adapter.ReadRealAsync("DB1.DBD0");

连接管理

S7 协议一个连接持有一个 Session。S7-1200/1500 默认最大并发连接数:

型号OP 连接S7 连接其他
S7-120038HMI/工程师同时连
S7-1500816
S7-1500 高规格1664

超过上限后新连接被拒绝。Darra 的连接池设计上保持一个固定连接复用, 避免对端耗尽。

批量读写优化

S7 支持一次请求读 / 写多个不连续项 (最多 19 项, PDU 长度 240 字节):

var batch = adapter.CreateBatch();
batch.Add("DB1.DBW0", 2); // 读 INT
batch.Add("DB1.DBD4", 4); // 读 REAL
batch.Add("M10.0", 1); // 读 BOOL
var results = await batch.ReadAsync();

适配器自动把多项请求打包到一个 PDU, 往返 1 次搞定。

DB 结构导入

在 IDE 中可以从 TIA Portal 导出的 Excel 或 XML 文件导入 DB 结构:

项目树 → 通讯 → S7 连接 → 右键 → 导入 DB 定义

导入后自动在变量表里生成对应符号, 地址自动填 DB<n>.DBx<offset>, 便于后续代码引用。

定时读取与事件订阅

适配器支持两种读取模式:

  1. 周期轮询: 固定间隔读, 低延迟要求
  2. 变化订阅: 在 Darra 侧做比对, 变化时触发事件, 减少下游处理量
adapter.Subscribe("DB1.DBW0", TimeSpan.FromMilliseconds(100), (addr, oldVal, newVal) => {
Console.WriteLine($"{addr}: {oldVal}{newVal}");
});

时间同步

S7-300/400 的 SFC1 / SFC20 可以同步系统时钟。Darra 侧可以周期下发主机时间:

await adapter.WriteClockAsync(DateTime.Now);
var plcTime = await adapter.ReadClockAsync();

适合边缘计算场景需要 PLC 时间与上位一致。

错误码映射

S7 Error含义处理
0x00成功
0x05地址错误检查 DB 号、偏移
0x0A请求项不存在检查 DB 是否已下载
0x0B对象类型不匹配检查是否 ARRAY of BYTE
0x81用户会话权限不足开启 PUT/GET
0xD2数据类型不支持改用合适的类型
0xD8长度错误缩小请求长度

排错

症状处理
连接超时检查 IP、Rack/Slot、端口 102
认证失败TIA 里开 PUT/GET
读取返回 0DB 被"优化块访问"保护
偶发错误 0x0A刚下载完 CPU, 等几秒
低速 (100ms+)PDU 小, 开启批量读
中文字符串乱码STRING 类型按 Windows-1252, 改用 WSTRING