1.2 通信角色说明
设备 | 角色 | 功能 |
| 组态王 | 客户端/主站 | 发起读/写请求,显示数据 |
| S7-1200 | 服务器/从站 | 响应读/写请求,提供数据 |
1.3 通信特点
特性 | 说明 |
通信类型 | 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 服务器 |
组态王 | V6.55 | V6.60+ | 支持 Modbus TCP 驱动 |
MB_SERVER 库 | V2.0+ | 最新版本 | TIA Portal 内置 |
操作系统 | Windows 7/10/11 | Windows 10/11 | 运行组态王 |
2.2 硬件要求
设备 | 型号 | 说明 |
| S7-1200 | CPU1212C/1214C/1215C/1217C | 带 PROFINET 接口 |
| PC/服务器 | 任意 Windows PC | 运行组态王 |
| 网线 | 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 接口:
IP 地址:如 192.168.0.1
子网掩码:255.255.255.0
进入「设备组态」→ 点击 CPU 上的 PROFINET 接口
在「常规」→「以太网地址」中设置:
第三步:添加 Modbus TCP 通信块
打开程序块:
展开「程序块」→「MAIN」
找到「通信」→「其它」→「Modbus TCP」
添加 MB_SERVER 块:
拖拽「MB_SERVER」到 OB1 或 FB/FC 中
系统会自动生成背景数据块(如 DB3)
配置 MB_SERVER 参数:
参数 | 设置值 | 说明 |
| CONNECT | 新建连接 | 指向 Modbus TCP 连接配置 |
| DISC_IO | | 离散输入/输出区 |
| HOLD_REG | | 保持寄存器区 |
| MB_HOLD_REG | | 保持寄存器指针 |
第四步:配置 Modbus TCP 连接
创建连接配置:
在「程序块」→「通信」→「其它」→「Modbus TCP」
右键「添加新连接」
配置连接参数:
参数 | 设置值 | 说明 |
| 连接 ID | | 唯一连接标识 |
| IP 地址 | 0.0.0.0 | 监听所有 IP(或指定组态王 IP) |
| 端口号 | 502 | Modbus TCP 默认端口 |
| 连接类型 | TCP | 选择 TCP 连接 |
| 主动建立连接 | 否 | PLC 作为服务器被动监听 |
第五步:创建数据块
创建 DB 块:
右键「程序块」→「添加新块」→「数据块」
命名为「Modbus_Data」
取消「优化的块访问」,使用绝对地址
定义变量:
变量名称 | 数据类型 | 地址 | 说明 |
Coil_Out | Array[0..99] Of Bool | DB1.DBX0.0 | 线圈输出区 |
Discrete_In | Array[0..99] Of Bool | DB1.DBX100.0 | 离散输入区 |
Hold_Reg | Array[0..99] Of Word | DB1.DBW200 | 保持寄存器区 |
Input_Reg | Array[0..99] Of Word | DB1.DBW400 | 输入寄存器区 |
第六步:编写通信程序
// 主程序 OB1// 调用 MB_SERVER 块"MB_Server_Instance"( CONNECT := 'Modbus_TCP_Connection', // 连接配置 DISC_IO := P#"Modbus_Data".Coil_Out, // 离散 I/O 区 HOLD_REG := P#"Modbus_Data".Hold_Reg[0], // 保持寄存器区 MB_HOLD_REG := P#"Modbus_Data".Hold_Reg[0], // 保持寄存器指针 MB_MODE := 0, // 服务器模式 BUSY => MB_Busy, // 忙标志 ERROR => MB_Error, // 错误标志 STATUS => MB_Status // 状态代码);第七步:编译并下载
编译项目:
点击「编译」→「编译全部」
检查是否有错误
下载 PLC 程序:
连接 S7-1200 PLC
下载程序到 PLC
将 PLC 切换到RUN 模式
---
四、组态王侧配置
第一步:创建组态王工程
打开组态王软件
点击「新建工程」,输入工程名称和路径
完成工程创建向导
第二步:定义 Modbus TCP 设备
进入设备配置:
在工程浏览器中展开「设备」
右键「COM1」或「网络」→「新建」
选择设备驱动:
选择「PLC」→「Modbus」→「Modbus TCP」→「TCP」
点击「下一步」
配置设备参数:
参数 | 设置值 | 说明 |
| 设备名称 | S7-1200 | 自定义设备名称 |
| IP 地址 | 192.168.0.1 | S7-1200 的 IP 地址 |
| 端口号 | 502 | Modbus TCP 默认端口 |
| 设备地址 | 1 | Modbus 从站地址 |
| 数据格式 | 1 个起始位,8 个数据位,无校验,1 个停止位 | 默认设置 |
第三步:定义变量
进入变量配置:
在工程浏览器中展开「数据库」
右键「变量」→「新建」
添加变量:
变量名称 | 数据类型 | Modbus 地址 | 读写 | 说明 |
Motor_Start | 离散 | 00001 | 读写 | 电机启动 |
Motor_Stop | 离散 | 00002 | 读写 | 电机停止 |
Motor_Running | 离散 | 10001 | 只读 | 电机运行 |
Motor_Fault | 离散 | 10002 | 只读 | 电机故障 |
Speed_Setpoint | 整数 | 40001 | 读写 | 速度设定 |
Speed_Actual | 整数 | 40002 | 只读 | 实际速度 |
Motor_Current | 实数 | 40003 | 只读 | 电机电流 |
Motor_Temp | 实数 | 40005 | 只读 | 电机温度 |
Fault_Code | 整数 | 40007 | 只读 | 故障代码 |
Part_Count | 长整数 | 40008 | 读写 | 计数 |
配置变量属性:
选择对应的设备(S7-1200)
设置寄存器类型(线圈/离散/保持寄存器/输入寄存器)
设置读写属性
设置数据类型和转换格式
第四步:设计画面
创建画面:
在工程浏览器中展开「画面」
右键「新建画面」
添加控件:
控件类型 | 功能 | 关联变量 |
按钮 | 启动/停止 | Motor_Start/Motor_Stop |
指示灯 | 状态显示 | Motor_Running/Motor_Fault |
输入框 | 数值输入 | Speed_Setpoint |
文本显示 | 数值显示 | Speed_Actual/Motor_Current |
报警窗口 | 报警显示 | Fault_Code |
趋势图 | 曲线显示 | 历史数据 |
配置控件属性:
双击控件进入属性设置
在「变量连接」中关联数据库变量
设置外观、颜色、动画等
第五步:配置报警和历史
报警配置:
在工程浏览器中展开「报警」
配置报警变量和报警级别
设置报警记录和显示
历史数据配置:
在工程浏览器中展开「历史数据」
配置需要记录的变量
设置采样周期和存储方式
k第六步:编译并运行
编译工程:
点击「工程」→「全部编译」
检查是否有错误
运行工程:
点击「文件」→「切换到 View 运行系统」
或按 F5 运行
查看通信状态和数据
---
五、数据交换格式详解
5.1 Modbus 功能码
功能码 | 名称 | S7-1200 映射 | 组态王寄存器类型 |
01 | 读线圈 | %Q/M 区 | 线圈(0xxxx) |
02 | 读离散输入 | %I/M 区 | 离散输入(1xxxx) |
03 | 读保持寄存器 | DB 块 | 保持寄存器(4xxxx) |
04 | 读输入寄存器 | DB 块/IW 区 | 输入寄存器(3xxxx) |
05 | 写单线圈 | %Q/M 区 | 线圈(0xxxx) |
06 | 写单寄存器 | DB 块 | 保持寄存器(4xxxx) |
15 | 写多线圈 | %Q/M 区 | 线圈(0xxxx) |
16 | 写多寄存器 | DB 块 | 保持寄存器(4xxxx) |
5.2 地址映射表(典型配置)
组态王地址 | 功能码 | S7-1200 地址 | 数据类型 | 说明 |
00001-00100 | 01 | DB1.DBX0.0-DB1.DBX12.3 | Bool | 线圈输出 |
10001-10100 | 02 | DB1.DBX100.0-DB1.DBX112.3 | Bool | 离散输入 |
40001-40100 | 03 | DB1.DBW200-DB1.DBW398 | Word | 保持寄存器 |
30001-30100 | 04 | DB1.DBW400-DB1.DBW598 | Word | 输入寄存器 |
5.3 数据类型转换
组态王类型 | S7-1200 类型 | 说明 |
离散/开关 | Bool | 1 位 |
整数 | Int/Word | 16 位 |
长整数 | DInt | 32 位 |
实数 | Real | 32 位浮点 |
字符串 | Array[Char] | 需特殊处理 |
5.4 典型读写示例
读取保持寄存器:
请求:00 01 00 00 00 06 01 03 00 C8 00 0A响应:00 01 00 00 00 17 01 03 14 [数据 20 字节]写入单寄存器:
请求:00 02 00 00 00 09 01 06 00 C8 03 E8响应:00 02 00 00 00 06 01 06 00 C8 03 E8---
六、编程示例
6.1 S7-1200 服务器程序(SCL)
// 数据块 DB1 "Modbus_Server_Data"(取消优化块访问)DATA_BLOCK "Modbus_Server_Data"STRUCT // 线圈区(功能码 01/05/15) Coil_Out : Array[0..99] Of Bool; // DB1.DBX0.0 // 离散输入区(功能码 02) Discrete_In : Array[0..99] Of Bool; // DB1.DBX100.0 // 保持寄存器区(功能码 03/06/16) Hold_Reg : Array[0..99] Of Word; // DB1.DBW200 // 输入寄存器区(功能码 04) Input_Reg : Array[0..99] Of Word; // DB1.DBW400 // 通信状态 Server_Ready : Bool; // DB1.DBX600.0 Comm_Error : Bool; // DB1.DBX600.1 Error_Code : Word; // DB1.DBW602 Client_Connected : Bool; // DB1.DBX600.2END_STRUCTEND_DATA_BLOCK// 主程序 OB1FUNCTION_BLOCK "FB_Modbus_Server"VAR // MB_SERVER 实例 "MB_Server_Instance" : MB_SERVER; // 连接配置 "Modbus_TCP_Connection" : TCON_Modbus; // 状态变量 MB_Busy : Bool; MB_Error : Bool; MB_Status : Word;END_VAR// 连接配置初始化"Modbus_TCP_Connection".connectionId := W161;"Modbus_TCP_Connection".connectionType := W161; // TCP"Modbus_TCP_Connection".activeEstablish := FALSE; // 被动监听"Modbus_TCP_Connection".localPort := 502;// 调用 MB_SERVER 块"MB_Server_Instance"( CONNECT := 'Modbus_TCP_Connection', DISC_IO := P#"Modbus_Server_Data".Coil_Out, HOLD_REG := P#"Modbus_Server_Data".Hold_Reg[0], MB_HOLD_REG := P#"Modbus_Server_Data".Hold_Reg[0], BUSY => MB_Busy, ERROR => MB_Error, STATUS => MB_Status);// 状态处理IF MB_Error THEN "Modbus_Server_Data".Comm_Error := TRUE; "Modbus_Server_Data".Error_Code := MB_Status;ELSE "Modbus_Server_Data".Comm_Error := FALSE;END_IF;// 服务器就绪标志"Modbus_Server_Data".Server_Ready := NOT MB_Busy;6.2 数据映射处理
// 将 PLC 内部数据映射到 Modbus 寄存器区// 保持寄存器映射"Modbus_Server_Data".Hold_Reg[0] := "Motor_Speed_Setpoint"; // 40001"Modbus_Server_Data".Hold_Reg[1] := "Motor_Speed_Actual"; // 40002"Modbus_Server_Data".Hold_Reg[2] := WORD("Motor_Current"); // 40003"Modbus_Server_Data".Hold_Reg[3] := WORD("Motor_Temp"); // 40004"Modbus_Server_Data".Hold_Reg[4] := "Fault_Code"; // 40005"Modbus_Server_Data".Hold_Reg[5] := "Part_Count_High"; // 40006"Modbus_Server_Data".Hold_Reg[6] := "Part_Count_Low"; // 40007// 线圈映射"Modbus_Server_Data".Coil_Out[0] := "Motor_Start"; // 00001"Modbus_Server_Data".Coil_Out[1] := "Motor_Stop"; // 00002"Modbus_Server_Data".Coil_Out[2] := "Motor_Reset"; // 00003"Modbus_Server_Data".Coil_Out[3] := "Alarm_Reset"; // 00004// 离散输入映射"Modbus_Server_Data".Discrete_In[0] := "Motor_Running"; // 10001"Modbus_Server_Data".Discrete_In[1] := "Motor_Fault"; // 10002"Modbus_Server_Data".Discrete_In[2] := "System_Ready"; // 100036.3 读取组态王写入的数据
// 从 Modbus 寄存器区读取数据到 PLC 内部变量// 读取组态王写入的设定值"Motor_Speed_Setpoint" := INT("Modbus_Server_Data".Hold_Reg[0]);"Motor_Start" := "Modbus_Server_Data".Coil_Out[0];"Motor_Stop" := "Modbus_Server_Data".Coil_Out[1];"Motor_Reset" := "Modbus_Server_Data".Coil_Out[2];// 控制逻辑IF "Motor_Start" AND NOT "Motor_Stop" AND NOT "Motor_Fault" THEN "Motor_Running" := TRUE;END_IF;IF "Motor_Stop" OR "Motor_Fault" THEN "Motor_Running" := FALSE;END_IF;IF "Motor_Reset" THEN "Fault_Code" := 0; "Motor_Fault" := FALSE;END_IF;---
七、通信状态监控与诊断
7.1 MB_SERVER 状态代码
状态代码 | 含义 | 解决方案 |
| 无错误 | 正常 |
| 连接超时 | 检查网络连接 |
| 连接拒绝 | 检查 IP 和端口 |
| 无连接 | 等待客户端连接 |
| 连接断开 | 检查网络稳定性 |
| 数据错误 | 检查寄存器地址 |
| 功能码错误 | 检查功能码支持 |
| 从站地址错误 | 检查 Slave ID |
| 数据长度错误 | 检查数据长度配置 |
7.2 组态王通信状态
状态显示 | 含义 |
设备在线 | 通信正常 |
设备离线 | 通信中断 |
数据刷新 | 正常数据交换 |
通信超时 | 请求无响应 |
7.3 TIA Portal 在线监控
在 TIA Portal 中查看 CPU 的「在线与诊断」
查看「通信」→「Modbus TCP」连接状态
查看通信错误信息
监控 DB 块数据变化
7.4 组态王诊断
在组态王运行系统中查看「设备状态」
查看通信错误日志
使用「设备调试」功能测试连接
---
八、常见问题与解决方案
问题现象 | 可能原因 | 解决方案 |
无法连接 PLC | IP 地址不在同一网段 | 检查并统一 IP 网段 |
连接超时 | 端口号错误 | 确认端口为 502 |
连接被拒绝 | MB_SERVER 未运行 | 检查 PLC 程序和 RUN 模式 |
数据读取失败 | 寄存器地址错误 | 检查地址映射(注意偏移) |
功能码不支持 | 功能码配置错误 | 确认支持的功能码 |
从站地址错误 | 设备地址不匹配 | 确认从站地址为 1 |
频繁通信中断 | 网线质量差 | 更换高质量网线 |
数据值异常 | 字节顺序错误 | 检查高低字节顺序 |
DB 块访问失败 | 优化块访问启用 | 禁用优化块访问 |
多个客户端冲突 | 连接数超限 | 减少连接或升级 PLC |
MB_SERVER 报错 | 连接配置错误 | 检查 CONNECT 参数 |
防火墙阻止 | PC 防火墙设置 | 关闭防火墙或添加例外 |
组态王变量不更新 | 变量地址配置错误 | 检查变量寄存器类型和地址 |
数据跳动 | 通信周期过短 | 延长通信周期 |
中文显示乱码 | 字符编码问题 | 统一使用 ASCII 或 Unicode |
---
九、配置要点总结
配置项 | 关键要点 |
通信协议 | Modbus TCP(S7-1200 作为服务器) |
IP 地址 | 同一网段,不能冲突 |
端口号 | 默认 502 |
从站地址 | 组态王中设备地址通常为 1 |
连接配置 | MB_SERVER 的 CONNECT 参数正确 |
数据指针 | 使用 P格式(如 PDB1.DBW0 BYTE 200) |
DB 块优化 | 必须禁用优化块访问 |
功能码 | 01/02/03/04/05/06/15/16 |
地址映射 | 注意 Modbus 地址与 PLC 地址对应 |
运行模式 | PLC 需切换到 RUN 模式 |
防火墙 | PC 防火墙需允许 502 端口 |
网络连接 | 使用 CAT5e 及以上标准网线 |
数据类型 | 组态王与 PLC 数据类型要匹配 |
通信周期 | 合理设置,避免过快导致通信拥堵 |
---
十、推荐参考资料
资料名称 | 来源 |
S7-1200 Modbus TCP 通信手册 | 西门子工业支持中心 |
MB_SERVER 功能块使用说明 | TIA Portal 帮助文档 |
组态王用户手册 | 亚控科技官网 |
组态王 Modbus TCP 驱动说明 | 亚控科技官网 |
Modbus TCP 协议规范 | Modbus 组织官网 |
---
十一、总结
S7-1200 与组态王的 Modbus TCP 通信是国内工业自动化的经典方案,具有以下优势:
优势 | 说明 |
标准协议 | Modbus TCP 是开放标准,兼容性好 |
配置简单 | TIA Portal 内置 MB_SERVER 块,组态王驱动成熟 |
功能丰富 | 支持数据采集、报警、历史、趋势等 |
成本优化 | 无需额外通信模块,组态王性价比高 |
扩展灵活 | 支持多个客户端连接 |
兼容性好 | 支持标准 Modbus TCP 客户端 |
本土化 | 组态王是国产软件,中文支持好 |
配置流程简图
重要提示
S7-1200 作为 Modbus TCP 服务器,被动监听连接IP 地址必须在同一网段,不能冲突端口号默认为 502,如有修改需同步配置DB 块必须禁用优化块访问,使用绝对地址组态王中设备地址通常为 1PC 防火墙需允许 502 端口,否则连接会被阻止注意地址映射关系,Modbus 地址与 PLC 地址要对应数据类型要匹配,Bool/Word/Real 等要正确对应通信周期要合理,避免过快导致通信拥堵组态王变量地址格式:0xxxx=线圈,1xxxx=离散,3xxxx=输入寄存器,4xxxx=保持寄存器 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!