西门子S7-1200与S7-1200的 Modbus TCP 通讯示例 实现功能: S7-1215C作为客户端,S7-1217C作为服务器,S7-1215C读取S7-1217C的40001~40008的数据并存储到MW100 ~ MW114, 将MW116 ~ MW130 的数据写入到S7-1217C的 40009~40016
两台西门子S7-1200玩转Modbus TCP通信,手把手实战教学
最近在项目里碰到个需求,要让两台S7-1200 PLC通过Modbus TCP交换数据。具体来说,1215C当客户端去读1217C服务器里的40001到40008这8个寄存器,存到自己MW100到MW114;反过来还得把自己MW116到MW130的数据写到服务器的40009到40016。搞完这波操作,顺手整理了个流程,分享给需要的老铁们。
硬件和软件准备
先确认手头设备:S7-1215C(客户端)和S7-1217C(服务器)各一台,网线直连或者走交换机都行。软件必须用TIA Portal(V16或更高版本支持Modbus TCP指令),两台PLC的IP地址得配到同一网段,比如192.168.0.15和192.168.0.17。
PLC服务器端配置(S7-1217C)
服务器端其实不用写复杂代码,重点是把数据映射到Modbus地址上。打开TIA Portal,给1217C添加个DB块,比如命名为MBSERVERDATA,里面建8个Int类型变量对应40009-40016,再建8个Int变量对应40001-40008。接着在OB1里拖一个MB_SERVER指令块:
scss
MB_SERVER(
REQ := TRUE, // 保持常通
MB_HOLD_REG => P#DB1.DBX0.0 WORD 16, // 指向40001-40016的存储区
CONNECT := 背景DB块自动生成, // 默认端口502
ERROR => ,
STATUS => );
这里MBHOLDREG直接关联到刚才的DB块地址,16个Word刚好覆盖40001到40016。重点提示:40001对应的Modbus地址实际是偏移量0,所以40001对应DB1.DBW0,40009则对应DB1.DBW16。
客户端编程(S7-1215C)
客户端需要干两件事:读数据+写数据。在TIA Portal里给1215C新建个DB块(比如DB101),用来存通信参数,然后主程序里用两个MB_CLIENT指令分别处理读写。
步骤1:初始化连接

西门子S7-1200与S7-1200的 Modbus TCP 通讯示例 实现功能: S7-1215C作为客户端,S7-1217C作为服务器,S7-1215C读取S7-1217C的40001~40008的数据并存储到MW100 ~ MW114, 将MW116 ~ MW130 的数据写入到S7-1217C的 40009~40016
在OB100(启动组织块)里初始化连接参数:
scss
MB_CLIENT_DB.Active := TRUE;
MB_CLIENT_DB.IP := '192.168.0.17'; // 服务器IP
MB_CLIENT_DB.Port := 502;
步骤2:读取服务器数据
在OB1里放第一个MB_CLIENT块负责读取:
sclassic
MB_CLIENT(
REQ := 上升沿触发, // 用时钟脉冲或按钮触发
MB_MODE := 0, // 0=读取模式
MB_DATA_ADDR:= 40001, // 起始地址
MB_DATA_LEN := 8, // 读8个Word
MB_DATA_PTR := P#M 100.0 WORD 8, // 存到MW100-MW114
DONE => 读取完成标志,
ERROR => 错误状态,
STATUS => 状态码);
这里MBDATAPTR用了指针直接指向MW区域。注意 :MW100到MW114实际占用8个Word(每个Word占2字节,所以100,102...114)。如果遇到数据类型问题,可以用PEEK指令把数据搬到指定区域。
步骤3:写入数据到服务器
再拖一个MB_CLIENT块处理写入:
sclassic
MB_CLIENT(
REQ := 上升沿触发,
MB_MODE := 1, // 1=写入模式
MB_DATA_ADDR:= 40009, // 目标地址
MB_DATA_LEN := 8,
MB_DATA_PTR := P#M 116.0 WORD 8, // 从MW116-MW130取数据
DONE => 写入完成标志,
ERROR => ,
STATUS => );
坑点预警 :写入前确保MW116-MW130的数据已经更新,可以用POKE指令把数据打包到连续地址。
调试翻车现场实录
- 问题1:STATUS返回16#8383
大概率是IP地址配错或者服务器没启动。先ping一下PLC的IP,再检查服务器MB_SERVER的REQ是否常通。
- 问题2:数据对不上
检查地址偏移换算。比如Modbus的40001对应PLC的DB1.DBW0,而客户端读的时候起始地址填40001,但实际映射到服务器DB块的0偏移。
- 偷懒技巧:用TIA Portal的在线监控直接看DB块数据变化,或者抓个Wireshark包看Modbus报文内容。
总结
这套操作下来,基本上就能让两台S7-1200通过Modbus TCP互传数据了。重点就三句话:服务器开端口,客户端调指令,地址别算错。遇到问题先查状态码,再怼着数据地址换算表硬核核对。代码扔GitHub了(评论区自取),需要的老铁直接复制粘贴改参数就能用。
