抖音粉丝群1
『7x24小时有问必答』

一、通信概述

Modbus Slave 是一款Modbus 从站模拟/测试软件,运行在 PC 上,用于模拟 Modbus 从站设备。在此场景中,S7-1200 作为 Modbus TCP 客户端(主站),Modbus Slave 作为Modbus TCP 服务器(从站)

1.1 通信架构

1.png

1.2 通信角色说明(与 Modbus Poll 相反)

设备
角色
功能
S7-1200
客户端/主站
发起读/写请求
Modbus Slave
服务器/从站
响应读/写请求

1.3 与 Modbus Poll 的区别

特性
Modbus Poll
Modbus Slave
软件角色
Modbus 主站
Modbus 从站
S7-1200 角色
从站(MB_SERVER)
主站(MB_CLIENT)
通信块
MB_SERVER
MB_CLIENT
连接方式
被动监听
主动连接
应用场景
测试 S7-1200 从站功能
测试 S7-1200 主站功能

1.4 通信特点

特性
说明
通信类型
Modbus TCP(基于 TCP/IP)
功能码
01/02/03/04/05/06/15/16
传输距离
标准 100 米(可扩展)
通信周期
100ms ~ 1s 可调
端口号
默认 502
连接数
S7-1200 最多支持 8 个 Modbus TCP 连接

---

二、硬件与软件要求

2.1 软件要求

软件
最低版本
推荐版本
说明
TIA Portal(博途)
V15.1
V17/V18/V19
S7-1200 组态
S7-1200 固件
V2.0
V4.0+
支持 Modbus TCP 客户端
Modbus Slave
V6.0
V9.0+
Modbus 从站测试软件
MB_CLIENT 库
V2.0+
最新版本
TIA Portal 内置
操作系统
Windows 7/10/11
Windows 10/11
运行 Modbus Slave

2.2 硬件要求

设备
型号
说明
S7-1200
CPU 1212C/1214C/1215C/1217C
带 PROFINET 接口
PC 电脑
任意 Windows PC
运行 Modbus Slave
网线
CAT5e 及以上
标准工业以太网线
交换机
可选
多设备连接时使用

2.3 S7-1200 Modbus TCP 连接限制

S7-1200 型号
最大 Modbus TCP 连接数
说明
CPU 1211C
8 个
共享通信资源
CPU 1212C
8 个
共享通信资源
CPU 1214C
8 个
共享通信资源
CPU 1215C
8 个
共享通信资源
CPU 1217C
8 个
共享通信资源

---

三、配置步骤(S7-1200 侧)

第一步:创建 TIA Portal 项目

打开TIA Portal软件
点击「创建新项目」,输入项目名称
选择「添加新设备」

第二步:添加 S7-1200 CPU

添加 PLC
选择「控制器」→「SIMATIC S7-1200」→「CPU」
选择具体型号和固件版本
配置 PROFINET 接口
进入「设备视图」→ 点击 CPU 上的 PROFINET 接口
在「属性」→「以太网地址」中设置:
IP 地址:如  192.168.0.1
子网掩码:255.255.255.0

第三步:添加 Modbus TCP 通信块

打开程序块
展开「程序块」→「系统块」
找到「Communication」→「Modbus TCP」
添加 MB_CLIENT 块
拖拽「MB_CLIENT」到 OB1 或 FB/FC 中
系统会自动生成背景数据块(如 DB3)
配置 MB_CLIENT 参数
参数
设置值
说明
CONNECT
新建连接
指向 Modbus TCP 连接配置
MB_MODE
0/1/2/3
0=保持,1=读取,2=写入,3=写多个
MB_ADDR
1
Modbus 从站地址
MODE
0/1
0=保持寄存器,1=输入寄存器
DATA_ADDR
0
起始寄存器地址
DATA_LEN
10
读取/写入的数据长度
DATA_PTR
PDB1.DBW0 BYTE 20
数据存储区指针

第四步:配置 Modbus TCP 连接

创建连接配置
在「程序块」→「系统块」→「Modbus TCP」
右键「添加新连接」
配置连接参数
参数
设置值
说明
连接 ID
唯一连接标识
IP 地址
192.168.0.2
Modbus Slave 的 IP 地址
端口号
502
Modbus TCP 默认端口
连接类型
TCP
选择 TCP 连接
主动建立连接
PLC 作为客户端主动连接

第五步:创建数据块

创建 DB 块
右键「程序块」→「添加新块」→「数据块」
命名为「Modbus_Data」
取消「优化的块访问」,使用绝对地址
定义变量
变量名称
数据类型
地址
说明
Read_Req
Bool
DB1.DBX0.0
读取请求
Write_Req
Bool
DB1.DBX0.1
写入请求
Read_Data
Array[0..99] Of Word
DB1.DBW2
读取数据区
Write_Data
Array[0..99] Of Word
DB1.DBW202
写入数据区
Comm_Status
Word
DB1.DBW402
通信状态
Error_Code
Word
DB1.DBW404
错误代码

第六步:编写通信程序

// 主程序 OB1 或 FB

// 调用 MB_CLIENT 块(读取)

"MB_Client_Read"(

      CONNECT := 'Modbus_TCP_Connection',   // 连接配置

      MB_MODE := 1,                                     // 1=读取

      MB_ADDR := 1,                                     // 从站地址

      MODE := 0,                                          // 0=保持寄存器

      DATA_ADDR := 0,                                  // 起始地址

      DATA_LEN := 10,                                  // 数据长度

      DATA_PTR := P#"Modbus_Data".Read_Data[0], // 数据指针

      REQ := "Modbus_Data".Read_Req,            // 读取请求

      BUSY =>  MB_Busy,                               // 忙标志

      MODE =>  MB_Mode_Status,                     // 模式状态

      DONE =>  MB_Done,                               // 完成标志

      ERROR =>  MB_Error,                            // 错误标志

      STATUS =>  MB_Status                           // 状态代码

);

// 调用 MB_CLIENT 块(写入)

"MB_Client_Write"(

      CONNECT := 'Modbus_TCP_Connection',

      MB_MODE := 2,                                     // 2=写入

      MB_ADDR := 1,

      MODE := 0,

      DATA_ADDR := 10,                                 // 写入起始地址

      DATA_LEN := 10,

      DATA_PTR := P#"Modbus_Data".Write_Data[0],

      REQ := "Modbus_Data".Write_Req,

      BUSY =>  MB_Busy,

      DONE =>  MB_Done,

      ERROR =>  MB_Error,

      STATUS =>  MB_Status

);

第七步:编译并下载

编译项目
点击「编译」→「编译全部」
检查是否有错误
下载 PLC 程序
连接 S7-1200 PLC
下载程序到 PLC
将 PLC 切换到RUN 模式

---

四、Modbus Slave 软件配置

第一步:安装 Modbus Slave

下载 Modbus Slave 软件(https://www.modbustools.com)
安装软件到 PC
启动 Modbus Slave

第二步:配置连接

点击「Connection」→「Connect」配置连接参数:
参数
设置值
说明
Connection
Modbus TCP
选择 TCP 连接
TCP/IP Setup
点击配置
进入 IP 配置
IP Address
192.168.0.2
PC 的 IP 地址
Port
502
Modbus TCP 默认端口
Slave ID
1
Modbus 从站地址

第三步:配置数据区

点击「Setup」→「Slave Definition」配置从站参数:
参数
设置值
说明
Slave ID
1
从站地址(与 PLC 配置一致)
Function
03-Holding Register
功能码
Address
0
起始地址
Quantity
100
寄存器数量
Scan Rate
1000 ms
扫描周期

第四步:设置初始数据

在数据显示窗口中
双击寄存器单元格
输入初始值
按 Enter 确认
配置数据变化(可选):
点击「Display」→「Options」
设置数据自动递增/递减
模拟实际设备数据变化

第五步:开始监听

点击「Connection」→「Connect」开始监听
等待 PLC 主动连接
查看连接状态和数据交换

---

五、数据交换格式详解

5.1 Modbus 功能码

功能码
名称
S7-1200 映射
说明
01
读线圈
%Q/M 区
读布尔输出
02
读离散输入
%I/M 区
读布尔输入
03
读保持寄存器
DB 块
读写字数据
04
读输入寄存器
DB 块/IW 区
读字数据
05
写单线圈
%Q/M 区
写布尔输出
06
写单寄存器
DB 块
写字数据
15
写多线圈
%Q/M 区
写多个布尔
16
写多寄存器
DB 块
写多个字

5.2 地址映射表(典型配置)

Modbus 地址
功能码
Modbus Slave 地址
S7-1200 地址
数据类型
说明
00001-00100
01
0-99
DB1.DBX0.0
Bool
线圈
10001-10100
02
0-99
DB1.DBX100.0
Bool
离散输入
40001-40100
03
0-99
DB1.DBW200
Word
保持寄存器
30001-30100
04
0-99
DB1.DBW400
Word
输入寄存器

5.3 Modbus TCP 报文格式

2.png

5.4 典型读写示例

读取保持寄存器
请求:00 01 00 00 00 06 01 03 00 00 00 0A

      (事务 ID)(协议)(长度)(从站)(功能码)(起始地址)(数量)

响应:00 01 00 00 00 17 01 03 14 [数据 20 字节]

写入多寄存器
请求:00 02 00 00 00 0D 01 10 00 0A 00 05 0A [数据 10 字节]

响应:00 02 00 00 00 06 01 10 00 0A 00 05

---

六、编程示例

6.1 完整客户端程序(SCL)

// 数据块 DB1 "Modbus_Client_Data"(取消优化块访问)

DATA_BLOCK "Modbus_Client_Data"

STRUCT

      // 控制命令

      Read_Req : Bool;                           // DB1.DBX0.0 读取请求

      Write_Req : Bool;                         // DB1.DBX0.1 写入请求

      Read_Trigger : Bool;                     // DB1.DBX0.2 读取触发

      Write_Trigger : Bool;                   // DB1.DBX0.3 写入触发

      // 读取数据区

      Read_Data : Array[0..99] Of Word; // DB1.DBW2 读取数据

      // 写入数据区

      Write_Data : Array[0..99] Of Word;// DB1.DBW202 写入数据

      // 通信状态

      Comm_Ready : Bool;                        // DB1.DBX402.0 通信就绪

      Comm_Busy : Bool;                         // DB1.DBX402.1 通信忙

      Comm_Error : Bool;                        // DB1.DBX402.2 通信错误

      Error_Code : Word;                        // DB1.DBW404 错误代码

      Status_Code : Word;                      // DB1.DBW406 状态代码

      // 应用数据

      Motor_Speed : Int;                        // DB1.DBW408 电机速度

      Motor_Temp : Int;                         // DB1.DBW410 电机温度

      Fault_Code : Word;                        // DB1.DBW412 故障代码

      Part_Count : DInt;                        // DB1.DBD414 计数

END_STRUCT

END_DATA_BLOCK

// 功能块 FB_Modbus_Client

FUNCTION_BLOCK "FB_Modbus_Client"

VAR

      // MB_CLIENT 实例

      "MB_Client_Read" : MB_CLIENT;

      "MB_Client_Write" : MB_CLIENT;

      // 连接配置

      "Modbus_TCP_Connection" : TCON_Modbus;

      // 状态变量

       Read_Busy : Bool;

       Read_Done : Bool;

       Read_Error : Bool;

       Read_Status : Word;

       Write_Busy : Bool;

       Write_Done : Bool;

       Write_Error : Bool;

       Write_Status : Word;

      // 状态机

       Step  : Int := 0;

       Read_Timer : TON_TIME;

       Write_Timer : TON_TIME;

END_VAR

// 连接配置初始化

"Modbus_TCP_Connection".connectionId := W161;

"Modbus_TCP_Connection".connectionType := W161;   // TCP

"Modbus_TCP_Connection".activeEstablish := TRUE;    // 主动连接

"Modbus_TCP_Connection".remoteAddress := P#"192.168.0.2:502";

// 状态机控制

CASE  Step  OF

      0: // 初始化

            "Modbus_Client_Data".Comm_Ready := FALSE;

             Step  := 1;

      1: // 定期读取数据

             Read_Timer(IN := TRUE, PT := T1S);   // 1 秒读取一次

            IF  Read_Timer.Q AND NOT  Read_Busy THEN

                  "Modbus_Client_Data".Read_Trigger := TRUE;

                   Read_Timer(IN := FALSE);

            END_IF;

            IF "Modbus_Client_Data".Read_Trigger THEN

                  "MB_Client_Read"(

                        CONNECT := 'Modbus_TCP_Connection',

                        MB_MODE := 1,               // 读取

                        MB_ADDR := 1,               // 从站地址

                        MODE := 0,                   // 保持寄存器

                        DATA_ADDR := 0,            // 起始地址

                        DATA_LEN := 10,            // 读取 10 个寄存器

                        DATA_PTR := P#"Modbus_Client_Data".Read_Data[0],

                        REQ := "Modbus_Client_Data".Read_Trigger,

                        BUSY =>  Read_Busy,

                        DONE =>  Read_Done,

                        ERROR =>  Read_Error,

                        STATUS =>  Read_Status

                  );

                  IF  Read_Done THEN

                        "Modbus_Client_Data".Read_Trigger := FALSE;

                        "Modbus_Client_Data".Comm_Ready := TRUE;

                        "Modbus_Client_Data".Comm_Error := FALSE;

                        // 数据处理

                        "Modbus_Client_Data".Motor_Speed := INT("Modbus_Client_Data".Read_Data[0]);

                        "Modbus_Client_Data".Motor_Temp := INT("Modbus_Client_Data".Read_Data[1]);

                        "Modbus_Client_Data".Fault_Code := "Modbus_Client_Data".Read_Data[2];

                  END_IF;

                  IF  Read_Error THEN

                        "Modbus_Client_Data".Comm_Error := TRUE;

                        "Modbus_Client_Data".Error_Code :=  Read_Status;

                  END_IF;

            END_IF;

             Step  := 2;

      2: // 等待写入请求

            IF "Modbus_Client_Data".Write_Req AND NOT  Write_Busy THEN

                  "Modbus_Client_Data".Write_Trigger := TRUE;

                   Step  := 3;

            ELSE

                   Step  := 1;

            END_IF;

      3: // 执行写入

            IF "Modbus_Client_Data".Write_Trigger THEN

                  "MB_Client_Write"(

                        CONNECT := 'Modbus_TCP_Connection',

                        MB_MODE := 2,               // 写入

                        MB_ADDR := 1,

                        MODE := 0,

                        DATA_ADDR := 10,          // 写入起始地址

                        DATA_LEN := 5,             // 写入 5 个寄存器

                        DATA_PTR := P#"Modbus_Client_Data".Write_Data[0],

                        REQ := "Modbus_Client_Data".Write_Trigger,

                        BUSY =>  Write_Busy,

                        DONE =>  Write_Done,

                        ERROR =>  Write_Error,

                        STATUS =>  Write_Status

                  );

                  IF  Write_Done THEN

                        "Modbus_Client_Data".Write_Trigger := FALSE;

                        "Modbus_Client_Data".Write_Req := FALSE;

                         Step  := 1;

                  END_IF;

                  IF  Write_Error THEN

                        "Modbus_Client_Data".Comm_Error := TRUE;

                        "Modbus_Client_Data".Error_Code :=  Write_Status;

                  END_IF;

            END_IF;

      ELSE

             Step  := 0;

END_CASE;

// 通信忙标志

"Modbus_Client_Data".Comm_Busy :=  Read_Busy OR  Write_Busy;

"Modbus_Client_Data".Status_Code :=  Read_Status;

6.2 数据映射处理

// 将 Modbus 读取的数据映射到 PLC 内部变量

// 从 Modbus Slave 读取的数据处理

"Motor_Speed_Setpoint" := INT("Modbus_Client_Data".Read_Data[0]);

"Motor_Temp_Setpoint" := INT("Modbus_Client_Data".Read_Data[1]);

"System_Fault" := "Modbus_Client_Data".Read_Data[2] <> 0;

// 准备写入 Modbus Slave 的数据

"Modbus_Client_Data".Write_Data[0] := WORD("Motor_Speed_Actual");

"Modbus_Client_Data".Write_Data[1] := WORD("Motor_Current");

"Modbus_Client_Data".Write_Data[2] := WORD("Part_Count_High");

"Modbus_Client_Data".Write_Data[3] := WORD("Part_Count_Low");

"Modbus_Client_Data".Write_Data[4] := "System_Status";

// 触发写入

IF "Data_Change_Flag" OR "Write_Timer".Q THEN

      "Modbus_Client_Data".Write_Req := TRUE;

END_IF;

6.3 多从站轮询示例

// 多 Modbus 从站轮询

CASE "Poll_Index" OF

      1: // 从站 1(Modbus Slave)

            "MB_Client_1"(

                  CONNECT := 'Connection_1',

                  MB_ADDR := 1,

                  DATA_ADDR := 0,

                  DATA_LEN := 10,

                  REQ := "Poll_Trigger",

                  DONE => "Poll_1_Done"

            );

      2: // 从站 2

            "MB_Client_2"(

                  CONNECT := 'Connection_2',

                  MB_ADDR := 2,

                  DATA_ADDR := 0,

                  DATA_LEN := 10,

                  REQ := "Poll_Trigger",

                  DONE => "Poll_2_Done"

            );

      3: // 从站 3

            "MB_Client_3"(

                  CONNECT := 'Connection_3',

                  MB_ADDR := 3,

                  DATA_ADDR := 0,

                  DATA_LEN := 10,

                  REQ := "Poll_Trigger",

                  DONE => "Poll_3_Done"

            );

END_CASE;

// 轮询切换

"Poll_Timer"(IN := TRUE, PT := T500MS);

IF "Poll_Timer".Q THEN

      "Poll_Index" := "Poll_Index" + 1;

      IF "Poll_Index" > 3 THEN

            "Poll_Index" := 1;

      END_IF;

      "Poll_Trigger" := TRUE;

      "Poll_Timer"(IN := FALSE);

ELSE

      "Poll_Trigger" := FALSE;

END_IF;

---

七、通信状态监控与诊断

7.1 MB_CLIENT 状态代码

状态代码
含义
解决方案
无错误
正常
连接超时
检查网络连接
连接拒绝
检查 IP 和端口
无连接
连接未建立
连接断开
检查网络稳定性
数据错误
检查寄存器地址
功能码错误
检查功能码配置
从站无响应
检查从站状态
数据长度错误
检查数据长度配置

7.2 Modbus Slave 状态显示

显示
颜色
含义
数值显示
黑色
正常数据
数值显示
红色
通信错误
状态栏
绿色
连接正常
状态栏
红色
连接断开
Tx 计数器
递增
接收请求
Rx 计数器
递增
发送响应
Err 计数器
递增
通信错误

7.3 TIA Portal 在线监控

在 TIA Portal 中查看 CPU 的「在线与诊断」
查看「通信」→「Modbus TCP」连接状态
查看通信错误信息
监控 DB 块数据变化

---

八、常见问题与解决方案

问题现象
可能原因
解决方案
无法连接 Modbus Slave
IP 地址不在同一网段
检查并统一 IP 网段
连接超时
端口号错误
确认端口为 502
连接被拒绝
Modbus Slave 未运行
检查软件是否启动
数据读取失败
寄存器地址错误
检查地址映射(注意偏移)
功能码不支持
功能码配置错误
确认支持的功能码
从站地址错误
MB_ADDR 不匹配
确认从站地址为 1
频繁通信中断
网线质量差
更换高质量网线
数据值异常
字节顺序错误
检查高低字节顺序
DB 块访问失败
优化块访问启用
禁用优化块访问
多个请求冲突
未做互锁处理
添加状态机控制
MB_CLIENT 报错
连接配置错误
检查 CONNECT 参数
防火墙阻止
PC 防火墙设置
关闭防火墙或添加例外
读取数据不变
Modbus Slave 数据未更新
检查 Slave 数据设置

---

九、配置要点总结

配置项
关键要点
通信协议
Modbus TCP(S7-1200 作为客户端)
IP 地址
同一网段,不能冲突
端口号
默认 502
从站地址
Modbus Slave 中 Slave ID 通常为 1
连接配置
MB_CLIENT 的 CONNECT 参数正确
数据指针
使用 P格式(如 PDB1.DBW0 BYTE 20)
DB 块优化
必须禁用优化块访问
功能码
01/02/03/04/05/06/15/16
地址映射
注意 Modbus 地址与 PLC 地址对应
状态机控制
避免多个请求同时发送
错误处理
添加通信错误处理和重试机制
防火墙
PC 防火墙需允许 502 端口
网络连接
使用 CAT5e 及以上标准网线

---

十、Modbus Poll vs Modbus Slave 对比

特性
Modbus Poll
Modbus Slave
软件角色
Modbus 主站
Modbus 从站
S7-1200 角色
从站(MB_SERVER)
主站(MB_CLIENT)
通信块
MB_SERVER
MB_CLIENT
连接方式
被动监听
主动连接
IP 配置
PLC 固定 IP,Poll 连接 PLC
Slave 固定 IP,PLC 连接 Slave
应用场景
测试 S7-1200 从站功能
测试 S7-1200 主站功能
数据流向
Poll 请求→PLC 响应
PLC 请求→Slave 响应

---

十一、推荐参考资料

资料名称
来源
S7-1200 Modbus TCP 通信手册
西门子工业支持中心
MB_CLIENT 功能块使用说明
TIA Portal 帮助文档
Modbus Slave 用户手册
Modbus Tools 官网
Modbus TCP 协议规范
Modbus 组织官网

---

十二、总结

S7-1200 与 Modbus Slave 的通信是Modbus TCP 主站测试的经典方案,具有以下优势:
优势
说明
标准协议
Modbus TCP 是开放标准,兼容性好
配置简单
TIA Portal 内置 MB_CLIENT 块
测试方便
Modbus Slave 直观显示数据
成本优化
无需额外通信模块
扩展灵活
支持多个从站连接
兼容性好
支持标准 Modbus TCP 服务器

配置流程简图

3.png

重要提示

S7-1200 作为 Modbus TCP 客户端,主动发起连接IP 地址必须在同一网段,不能冲突端口号默认为 502,如有修改需同步配置DB 块必须禁用优化块访问,使用绝对地址Modbus Slave 中 Slave ID 通常为1PC 防火墙需允许 502 端口,否则连接会被阻止使用状态机控制通信,避免多个请求冲突注意地址映射关系,Modbus 地址与 PLC 地址要对应

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码