西门子 S7-1200 与上位机通信选型实战:S7 协议 vs Modbus TCP
分类:plc | 时间:2026-10-08 15:22:58 | 阅读:56
场景背景
给一条包装线做上位机监控,控制器是西门子 S7-1200(CPU 1214C DC/DC/DC),上位机是 C# WinForms,要实时读 60 个变量(速度、温度、计数、报警字),并在 HMI 触摸屏上同步显示。
选型时纠结了很久:到底用西门子自家的 S7 协议(S7.Net / Snap7),还是把所有数据映射到 Modbus TCP 寄存器让上位机读?这两种方案我都跑过一遍,下面把配置步骤、代码和实测数据都摆出来。

方案一:S7 协议直连(S7.Net / Snap7)
优点是不用改 PLC 程序,直接按 DB 块地址读写,变量名和 PLC 里一一对应。
先在 TIA Portal 里做两件事,缺一不可:
然后建一个全局 DB 块,取消勾选"优化的块访问"(否则没有绝对地址,S7.Net 读不到):
上位机侧用 S7.Net 读取:
注意:一定要"一次读回一整块再解析",而不是按变量逐个
方案二:Modbus TCP 映射(通用性更强)
如果上位机不是 C# 而是组态软件、或者要多品牌 PLC 统一接入,Modbus TCP 更省心。代价是要在 PLC 里写搬运程序。
S7-1200 做 Modbus TCP 从站,需要装指令库
再把要暴露的变量搬进保持寄存器数组:
上位机侧用 NModbus4 读 40001 起始的保持寄存器:
实测对比
同一台 S7-1200,读 60 个变量,采样周期 500ms,连续跑 1 小时:
结论:纯西门子环境用 S7 协议(省事、不用动 PLC 程序、可整块读);多品牌混合或上位机是第三方组态软件时用 Modbus TCP(通用、但要多写 PLC 搬运码、且没有认证)。

踩过的坑
S7-1200 默认固件是"仅允许 HMI 连接",不勾"允许 PUT/GET"的话,S7.Net 连上去立刻报
DB 块如果忘了取消"优化的块访问",
Modbus 的寄存器地址有两种数法:协议地址从 0 开始,文档地址从 40001 开始。NModbus4 用的是协议地址,所以你想读 40010 要传 9,不是 10。这个差一位的坑几乎每个人都踩过。
Real 类型在 Modbus 里是大端双字,而 .NET 读到的是
用 S7.Net 一定要在 finally 里
小结
通信选型没有绝对优劣,只有场景匹配。西门子单品牌、要快速落地,S7 协议是首选;一旦涉及多品牌、或者要用通用组态软件,Modbus TCP 的通用性就值回票价。无论选哪种,把"整块批量读"和"连接必须归还"这两条守住,稳定性就有基本保障。
S7-1200PLCModbusTIA通信
给一条包装线做上位机监控,控制器是西门子 S7-1200(CPU 1214C DC/DC/DC),上位机是 C# WinForms,要实时读 60 个变量(速度、温度、计数、报警字),并在 HMI 触摸屏上同步显示。
选型时纠结了很久:到底用西门子自家的 S7 协议(S7.Net / Snap7),还是把所有数据映射到 Modbus TCP 寄存器让上位机读?这两种方案我都跑过一遍,下面把配置步骤、代码和实测数据都摆出来。

方案一:S7 协议直连(S7.Net / Snap7)
优点是不用改 PLC 程序,直接按 DB 块地址读写,变量名和 PLC 里一一对应。
先在 TIA Portal 里做两件事,缺一不可:
1. CPU 属性 → 防护与安全 → 连接机制 ☑ 允许来自远程对象的 PUT/GET 通信访问 ← 不勾这个,上位机连不上 2. 属性 → 常规 → PROFINET 接口 → 以太网地址 IP: 192.168.0.10 子网掩码: 255.255.255.0
然后建一个全局 DB 块,取消勾选"优化的块访问"(否则没有绝对地址,S7.Net 读不到):
DB1 "DataBlock"(非优化访问) 偏移 0.0 Real Speed 速度 偏移 4.0 Real Temperature 温度 偏移 8.0 DInt Counter 计数 偏移 12.0 Word AlarmWord 报警字
上位机侧用 S7.Net 读取:
csharp using S7.Net; // 建立连接(Rack 0 / Slot 1 是 S7-1200 的默认值) var plc = new Plc(CpuType.S71200, "192.168.0.10", 0, 1); plc.Open(); // 一次性读回整个 DB1 的前 14 个字节,再按偏移解析 byte[] buf = plc.ReadBytes(DataType.DataBlock, 1, 0, 14); double speed = S7.Net.Types.Real.FromByteArray(buf.Skip(0).Take(4).ToArray()); double temp = S7.Net.Types.Real.FromByteArray(buf.Skip(4).Take(4).ToArray()); int cnt = S7.Net.Types.DInt.FromByteArray(buf.Skip(8).Take(4).ToArray()); ushort alarm = S7.Net.Types.Word.FromByteArray(buf.Skip(12).Take(2).ToArray());
注意:一定要"一次读回一整块再解析",而不是按变量逐个
Read。S7 协议每次请求都有往返开销,逐变量读 60 个变量就是 60 次往返,实测要 900ms 以上。方案二:Modbus TCP 映射(通用性更强)
如果上位机不是 C# 而是组态软件、或者要多品牌 PLC 统一接入,Modbus TCP 更省心。代价是要在 PLC 里写搬运程序。
S7-1200 做 Modbus TCP 从站,需要装指令库
MB_SERVER:scl
// OB1 中调用 MB_SERVER(需先安装 "MODBUS TCP" 指令库)
"MB_SERVER_DB"(
DISCONNECT := FALSE,
CONNECT_ID := 1,
IP_PORT := 502, // Modbus 标准端口
MB_HOLD_REG:= "ModbusRegs".Reg, // 映射到保持寄存器数组
ND_DR := 0,
DR := 0,
NDR := #NDR,
DR_ := #DR,
ERROR := #ERROR,
STATUS := #STATUS);
再把要暴露的变量搬进保持寄存器数组:
scl
// 每个 Real 占 2 个寄存器(32 位)
"ModbusRegs".Reg[0] := REAL_TO_WORD_ARRAY("DB1".Speed);
"ModbusRegs".Reg[2] := REAL_TO_WORD_ARRAY("DB1".Temperature);
"ModbusRegs".Reg[4] := DINT_TO_WORD_ARRAY("DB1".Counter);
上位机侧用 NModbus4 读 40001 起始的保持寄存器:
csharp
var client = new TcpClient("192.168.0.10", 502);
var master = ModbusIpMaster.CreateIp(client);
// 起始地址 0 对应 40001,一次读 6 个寄存器
ushort[] regs = master.ReadHoldingRegisters(0, 6);
float speed = ModbusToFloat(regs, 0);
实测对比
同一台 S7-1200,读 60 个变量,采样周期 500ms,连续跑 1 小时:
S7 协议(S7.Net) Modbus TCP
首次连接耗时 ~120 ms ~60 ms
单次读取 60 变量 ~28 ms(整块读) ~35 ms
需要改 PLC 程序 否 是(写搬运逻辑)
跨品牌通用性 仅西门子 全品牌通吃
安全机制 PUT/GET 需授权 无认证,纯明文
调试难度 地址要对齐 DB 偏移 寄存器地址要换算
结论:纯西门子环境用 S7 协议(省事、不用动 PLC 程序、可整块读);多品牌混合或上位机是第三方组态软件时用 Modbus TCP(通用、但要多写 PLC 搬运码、且没有认证)。

踩过的坑
S7-1200 默认固件是"仅允许 HMI 连接",不勾"允许 PUT/GET"的话,S7.Net 连上去立刻报
Connection refused,而且 TIA 里看不出来,要抓包才发现。这个开关藏在"防护与安全 → 连接机制"里。DB 块如果忘了取消"优化的块访问",
ReadBytes 会读到全 0——因为优化访问下变量顺序由编译器决定,没有绝对偏移。Modbus 的寄存器地址有两种数法:协议地址从 0 开始,文档地址从 40001 开始。NModbus4 用的是协议地址,所以你想读 40010 要传 9,不是 10。这个差一位的坑几乎每个人都踩过。
Real 类型在 Modbus 里是大端双字,而 .NET 读到的是
ushort[2],拼接时高低字顺序不能反,否则速度会变成 1e-38 这种诡异数字。用 S7.Net 一定要在 finally 里
plc.Close(),S7-1200 的并发连接数是有限的,连接泄漏跑半天就会连不上。小结
通信选型没有绝对优劣,只有场景匹配。西门子单品牌、要快速落地,S7 协议是首选;一旦涉及多品牌、或者要用通用组态软件,Modbus TCP 的通用性就值回票价。无论选哪种,把"整块批量读"和"连接必须归还"这两条守住,稳定性就有基本保障。
S7-1200PLCModbusTIA通信