各位做自动化集成的朋友,应该都遇到过这种场景:手头只有一台西门子 S7-1200 PLC 和一台旧的串口仪表,想把 PLC 当作 Modbus 从站,用 PC 上的调试软件直接读写 PLC 的寄存器,用来调试触摸屏、SCADA 或者第三方设备。网上关于 S7-1200 做 Modbus RTU 主站的文章很多,但做从站、尤其是配合 CM1241 通信模块和 Modbus Slave 调试软件的完整教程却比较零散。本文就围绕这套组合,从硬件接线、软件组态、指令库调用到联调验证,整理一条可以照着做的闭环路径。
在开始之前,先明确一下本文的技术范围:主控使用西门子 S7-1200 系列 PLC,通信模块使用 CM1241 RS232/422/485(型号通常为 6ES7241-1CH30-1XB0),PC 端调试工具使用 Modbus Slave(即 ModSlave),通信协议采用 Modbus RTU,PLC 侧是 Modbus 从站(Slave)。本文不涉及 S7-1200 作 Modbus 主站的内容,也不涉及 Profibus、Profinet 通信。
1. 背景与核心概念
1.1 这是一套什么通信方案
Modbus 是工业自动化领域最经典的串行通信协议之一,Modbus RTU 是其最常用的传输模式。RTU 模式下,数据以二进制帧格式传输,每个 8 位字节包含在两个十六进制字符中,通信线上表现为紧凑的二进制数据流。因为实现简单、稳定可靠,大量仪表、变频器、温控器、PLC 都支持 Modbus RTU。
CM1241 是西门子 S7-1200 的串行通信模块,支持 RS232、RS422、RS485 三种电气接口(取决于具体型号和拨码设置)。它的作用是让 S7-1200 通过串口与外部设备交换数据。
把这两个东西组合起来,就可以实现如下架构:
PC(运行 Modbus Slave 软件) | RS232/RS485 串口 | CM1241 通信模块 | S7-1200 CPU 内部数据区在这个架构中,Modbus Slave 软件模拟的是一个 Modbus 从站设备,它会向总线上的主站请求响应;但更常见的调试场景是反过来——PLC 作为从站,PC 上的 Modbus Poll(主站工具)或 Modbus Slave(从站模拟工具)配合使用。
这里需要先澄清一个容易混淆的点。Modbus Slave 软件本身是用来模拟从站的,它通常配合 Modbus Poll(主站模拟软件)一起使用。但在本文的场景里,我们的 S7-1200 要作为 Modbus 从站,而 PC 端需要有一个能发起请求的主站工具。那你可能会问:为什么标题里提到 Modbus Slave 软件?
实际工作中存在两种用法:
- 用法一:PC 用 Modbus Poll 做主站,PLC 做从站,这是最常见的调试方式。
- 用法二:PC 用 Modbus Slave 做从站,PLC 做主站,这是测试 PLC 主站功能的方式。
- 用法三:先用 Modbus Slave 模拟一个从站,验证 PC 串口和通信链路,再切换到 PLC 从站模式。
本文的核心是第一种用法,但在联调过程中,Modbus Slave 软件可以作为辅助工具先用回环方式验证串口通信是否正常,再切换到 PLC 作从站的测试。这样可以把问题分层,排除硬件链路故障。
1.2 为什么选择 CM1241 而不是 CB1241
S7-1200 做串口通信,有两条路线:
- 路线一:使用 CB1241 通信板(RS485),直接插在 CPU 上,不占用扩展机架位置。
- 路线二:使用 CM1241 通信模块(RS232/422/485),占用一个信号板或通信模块插槽,支持接口类型更多。
CB1241 只能做 RS485,而 CM1241 有不同型号,支持 RS232、RS422、RS485 三种标准。如果你的现场设备是 RS232 接口(比如某些老式仪表、条码枪),就必须选 CM1241 RS232 版本。如果设备是 RS485 且 CPU 上没有空闲的信号板插槽,也需要用 CM1241。
需要注意硬件版本差异:CM1241 RS232 的型号是 6ES7241-1AH30-1XB0,CM1241 RS422/485 的型号是 6ES7241-1CH30-1XB0。本文示例以 RS422/485 版本为主,RS232 版本的接线不同但软件配置思路一致。
1.3 通信帧格式速览
Modbus RTU 的帧格式比较固定,主要有以下几种:
- 读线圈(01H)
- 读离散输入(02H)
- 读保持寄存器(03H)
- 读输入寄存器(04H)
- 写单线圈(05H)
- 写单寄存器(06H)
- 写多个线圈(0FH)
- 写多个寄存器(10H)
一个完整的 RTU 请求帧包含:从站地址(1 字节)、功能码(1 字节)、数据(N 字节)、CRC 校验(2 字节,低字节在前)。帧与帧之间需要有至少 3.5 个字符时间的静默间隔。
S7-1200 的 Modbus RTU 指令库已经封装好了这些帧的组包、解析和 CRC 计算,我们不需要手动处理字节细节,但理解帧格式对排查通信故障很有帮助。
2. 环境准备与版本说明
2.1 硬件清单
本文使用的主要硬件如下,版本号以实际项目为准:
| 设备 | 型号/规格 | 说明 |
|---|---|---|
| PLC | 西门子 S7-1200 CPU 1214C DC/DC/DC | 固件版本 V4.x 或更高 |
| 通信模块 | CM1241 RS422/485,6ES7241-1CH30-1XB0 | 固件版本 V1.0 或更高 |
| PC | 带串口或 USB-RS485 转换器 | 用于连接 CM1241 串口 |
| 串口线 | RS485 屏蔽双绞线或 RS232 串口线 | 长度尽量短,建议小于 50 米 |
| USB 转串口工具 | USB-RS485 / USB-RS232 | 推荐带隔离的型号 |
如果你的 CPU 固件版本较老,建议先升级到 TIA Portal 支持的最新固件,避免指令库和硬件组态不兼容。
2.2 软件清单
- TIA Portal(博途),本文示例以 V15.1 或 V16 为参考,V13 SP1 以上版本界面略有差异但思路相同。
- STEP 7 Professional 软件包,用于 S7-1200 编程。
- Modbus Slave(ModSlave)调试软件,建议使用官方评估版或正版授权。Modbus Poll 作为主站模拟工具也需要准备,因为实际联调时需要主站发起请求。
- 串口调试助手(如 SSCOM、VSPD),用于辅助验证串口数据收发。
这里做一个重要的软件说明:网上流传的所谓“modbus slave 破解版”“modbus slave version 10.0.0 破解版”,我不推荐使用。这类调试工具本身价格不高,官方有功能完整的评估版本可以免费试用。破解软件容易携带病毒、后门,而且在工控机上运行风险极大。更关键的是,破解版可能在通信帧处理上有未知 bug,导致误判通信问题。建议从官网下载 Winfiol 的 Modbus Slave/Modbus Poll 评估版,或者使用开源替代工具(如 QModMaster、Modbus Poll 的开源实现)。
2.3 知识准备
在开始组态之前,需要确认你了解以下概念:
- Modbus 从站地址(Slave ID/Unit ID):本文设置为 1。
- 波特率、数据位、校验位、停止位:本文使用 9600 8 N 1,即波特率 9600,数据位 8,无校验,1 位停止位。实际项目中必须与对方设备保持一致。
- 保持寄存器(Holding Register):Modbus 中最重要的数据区,对应 PLC 的 DB 块或 M 区。
理解这些串口参数的意义很重要,因为 Modbus RTU 调试中 80% 的“通信超时”问题都是因为串口参数不一致导致的。
3. 硬件接线与通信参数规划
3.1 CM1241 RS422/485 端子定义
CM1241 RS422/485 模块正面有一个 15 针 D-sub 公头接口,需要自己制作或购买配套的 D-sub 15 针转接线。使用 RS485 时,通常只需要用到以下引脚:
- 引脚 3:T/R+(发送/接收正极,即 A 线或 D+)
- 引脚 8:T/R-(发送/接收负极,即 B 线或 D-)
- 引脚 5:GND(信号地,建议接)
部分模块的引脚号可能因型号批次不同有差异,接线前务必查看模块外壳上的印刷标识或手册。
3.2 与 USB-RS485 转换器的接线
一种常见的接线方式是:CM1241 的 RS485 接口通过 D-sub 15 引脚引出后,接到 USB-RS485 转换器的 A/B 端子。
接线关系:
- CM1241 T/R+(引脚 3)→ USB-RS485 转换器的 T/R+ 或 A 端
- CM1241 T/R-(引脚 8)→ USB-RS485 转换器的 T/R- 或 B 端
- CM1241 GND(引脚 5)→ USB-RS485 转换器的 GND
不同品牌的转换器对 A/B 的定义可能不同,有的标注 A+、B-,有的标注 D+、D-。如果通信不上,先把 A/B 线对调试试,这是 RS485 接线最常见的坑。
3.3 终端电阻与偏置电阻
RS485 总线两端需要接终端电阻,典型值为 120 欧姆。如果只有两台设备短距离通信(几米内),不接终端电阻有时也能工作,但长距离或高速率时建议按规范接。
CM1241 模块上没有内置终端电阻开关,需要外接或在 D-sub 连接器内焊接电阻。对于调试阶段的短距离连接,如果通信稳定,可以先不接;如果出现偶发通信错误,再接 120 欧终端电阻。
3.4 通信参数规划表
在开始组态之前,先在纸上或 Excel 里把通信参数定下来,避免后续修改:
| 参数名 | 值 | 说明 |
|---|---|---|
| 波特率 | 9600 | 也可以选 19200、38400 |
| 数据位 | 8 | Modbus RTU 固定为 8 位 |
| 校验位 | 无(None) | 可选偶校验 Even |
| 停止位 | 1 | 校验为 None 时建议 2 或 1,本文用 1 |
| 从站地址 | 1 | 范围 1~247 |
| 字节顺序 | Big Endian(大字序) | 西门子默认 |
这些参数后面在 TIA Portal 的组态和 Modbus Slave 软件设置中都要保持一致,任何一个不一致都可能导致通信失败。
4. TIA Portal 组态与硬件配置
4.1 创建项目并添加 CPU
打开 TIA Portal,创建新项目,在“项目树”中添加新设备,选择对应的 CPU 型号。
需要注意:如果你选的 CPU 固件版本与 CM1241 固件版本不匹配,组态时可能报错。建议在设备组态界面把 CPU 固件版本选为与实物一致的版本。
4.2 添加 CM1241 模块
在设备视图中,从硬件目录里找到“通信模块”→“RS232/RS422/RS485”→“CM1241 RS422/485”,拖拽到 CPU 左侧的插槽中。
S7-1200 的通信模块安装在 CPU 左侧,插入后 TIA Portal 会自动分配硬件标识符(Hardware Identifier),这个标识符后面写程序时要用到。
4.3 配置 CM1241 接口参数
选中 CM1241 模块,在“属性”→“接口选项”→“端口组态”中设置:
- 协议:Modbus(注意这里选 Modbus,不是自由口)
- 波特率:9600
- 数据位:8
- 校验:无
- 停止位:1
- 等时模式:不启用
同时需要勾选“使能 RS485 总线终端电阻”选项(如果硬件支持自动端接)。如果选项是灰色的,就手动外接电阻。
这里要特别说明:CM1241 在 Modbus RTU 模式下,接口参数里的“协议”必须选为 Modbus,否则后续调用 Modbus_Slave 指令时会报错。如果选了“自由口”(Freeport),则只能自己用 Send/Receive 指令收发裸数据,不能直接使用 Modbus 库指令。
4.4 配置 CPU 的 Modbus 保持寄存器区
S7-1200 做 Modbus 从站时,支持通过指令的背景 DB 或指针来映射保持寄存器区。一种最简单的做法是使用 M 区或 DB 区。
为了便于后续用 Modbus Slave 软件查看,我建议创建一个全局 DB 作为通信数据区。命名为“ModbusData”,里面定义:
- Array[0..99] of Int,对应 Modbus 保持寄存器地址 40001~40100
- 添加一个 Bool 数组用于线圈区(可选)
创建完成后,记得取消勾选“优化块访问”,这样才能被 Modbus 指令通过绝对地址访问。
4.5 编译与下载
组态完成后,先编译整个项目,修正可能的硬件组态错误。然后连接 PLC,点击下载,把硬件组态和程序下载到 PLC。
这一步如果能顺利完成,说明硬件组态没有问题。如果下载时报错,重点检查 CPU 固件版本和模块是否被正确识别。
5. 编写 PLC 程序:调用 Modbus 指令库
5.1 添加 Modbus RTU 指令库
TIA Portal 从 V13 SP1 开始,Modbus RTU 指令已经集成在“指令”→“通信”→“通信处理器”→“Modbus”下面。需要使用的指令有两个:
- MB_COMM_LOAD:用于初始化串口通信端口,设置波特率、校验、停止位等参数。
- MB_SLAVE:用于将 PLC 作为 Modbus 从站,处理主站发来的请求。
这两个指令需要成对使用,MB_COMM_LOAD 负责底层串口配置,MB_SLAVE 负责协议处理。
5.2 编写 MB_COMM_LOAD 初始化逻辑
建议在 OB1 或一个循环 OB 中调用 MB_COMM_LOAD,但要注意:该指令不应每个扫描周期都触发,通常使用一个仅在启动时置位的标志位控制,或者直接在每个扫描周期调用(指令内部有去重逻辑,但为了规范建议用边沿触发)。
示例:为 MB_COMM_LOAD 创建一个 FC 或直接在 OB1 中调用。以下是 OB1 中的调用示意图:
网络1:初始化串口 调用 MB_COMM_LOAD REQ := "InitReq" // 一个只在启动时置位一次的 M 位 PORT := 269 // CM1241 的硬件标识符,来自设备组态 BAUD := 9600 // 波特率 PARITY := 0 // 0=无校验,1=偶校验,2=奇校验 STOP_BITS := 1 // 停止位 FLOW_CTRL := 0 // 流控关闭 RTS_ON_DLY := 0 RTS_OFF_DLY := 0 RESP_TO := 1000 // 响应超时 ms DONE := "MB_COMM_LOAD_DONE" ERROR := "MB_COMM_LOAD_ERROR" STATUS := "MB_COMM_LOAD_STATUS"这里有几个参数需要重点说明:
- PORT:不是模块的插槽号,而是设备组态里的“硬件标识符”。你可以在设备组态中选中 CM1241,在“系统常量”标签页里查到,通常是十进制数,比如 269 或 257。也可以在 PLC 变量的“系统常量”里看到。写程序时建议直接拖拽系统常量“Local~CM1241_1”之类的符号名,避免硬编码。
- BAUD:波特率直接填数值 9600、19200 等。
- PARITY:注意 Modbus RTU 通常使用无校验或偶校验,不能使用奇校验(协议规范中未定义,但有些设备支持)。如果对端设备要求偶校验,这里填 1。
- RESP_TO:从站模式下,这个参数意义不大,因为从站是被动响应。但在主站模式下很关键。这里设置 1000ms 作为默认值。
5.3 编写 MB_SLAVE 从站逻辑
MB_SLAVE 指令需要在一个独立的组织块或循环中被反复调用,建议在 OB1 中每个扫描周期调用,也可以通过一个循环中断 OB 定时调用。
调用参数示例如下:
网络2:Modbus 从站处理 调用 MB_SLAVE MB_ADDR := 1 // 从站地址,即 Modbus Slave ID MB_HOLD_REG := "ModbusData".HoldReg // 指向保持寄存器数组的首地址 MB_MODE := 0 // 0=只读,不写保持寄存器;1=允许写保持寄存器 MB_DATA_PTR := "ModbusData".HoldReg // 数据区指针 MB_LEN := 100 // 保持寄存器数量 NDR := "MB_SLAVE_NDR" // 新数据到达标志 DR := "MB_SLAVE_DR" // 读请求标志 ERROR := "MB_SLAVE_ERROR" STATUS := "MB_SLAVE_STATUS"这里有一个容易出错的地方:MB_HOLD_REG 和 MB_DATA_PTR 都指向同一个保持寄存器数组。很多初学者会漏掉 MB_HOLD_REG,或者只填了 MB_DATA_PTR,导致读上来的数据全是 0。
5.4 关于“优化块访问”的注意事项
在 S7-1200 中,新创建的 DB 默认勾选了“优化块访问”。这种 DB 没有固定的偏移地址,Modbus 指令无法直接通过指针访问。必须取消“优化块访问”,DB 才会显示偏移地址。
操作路径:在 DB 属性中,取消勾选“优化块访问”,然后重新编译。编译后可以在 DB 的“偏移量”列看到类似 0.0、2.0、4.0 的地址。
如果你不想用 DB,也可以用 M 区作为保持寄存器区,但 M 区容量有限(S7-1200 根据型号不同,M 区大小不同),而且不利于数据管理。建议优先使用 DB。
5.5 完整程序结构示例
OB1 ├── 网络1:首次扫描调用 MB_COMM_LOAD 初始化串口 ├── 网络2:每个扫描周期调用 MB_SLAVE 处理 Modbus 请求 └── 网络3:将数据区的值实时刷新到保持寄存器(可选)OB1 示例代码(FBD/LAD 描述):
// 网络1 伪代码,实际在 LAD/FBD 中拖拽指令 CALL "MB_COMM_LOAD", "MB_COMM_LOAD_DB" REQ := "FirstScan" PORT := 269 BAUD := 9600 PARITY := 0 STOP_BITS := 1 FLOW_CTRL := 0 RTS_ON_DLY := 0 RTS_OFF_DLY := 0 RESP_TO := 1000 DONE := "CommLoadDone" ERROR := "CommLoadError" STATUS := "CommLoadStatus" // 网络2 伪代码 CALL "MB_SLAVE", "MB_SLAVE_DB" MB_ADDR := 1 MB_MODE := 1 MB_HOLD_REG := "ModbusData".HoldReg[0] MB_DATA_PTR := "ModbusData".HoldReg[0] MB_LEN := 100 NDR := "SlaveNDR" DR := "SlaveDR" ERROR := "SlaveError" STATUS := "SlaveStatus"6. Modbus Slave / Modbus Poll 软件配置
6.1 Modbus Slave 软件的作用
正如前文所说,Modbus Slave 软件本身是模拟从站的。但在联调过程中,它的定位是“先用来验证 PC 串口和链路是否正常”。
具体做法是:
- 先用 Modbus Slave 软件模拟一个从站,用 Modbus Poll 软件(或串口调试助手)发请求,确认 PC 的串口收发和协议帧正常。
- 再断开 Modbus Slave,把 PLC 切换为从站,用 Modbus Poll 直接读 PLC 的数据。
这样排错时可以快速定位是链路问题还是 PLC 程序问题。
6.2 使用 Modbus Poll 连接 PLC
如果你手头只有 Modbus Slave 软件而没有 Modbus Poll,建议去下载一个 Modbus Poll 评估版,它是 Winfiol 公司配套的另一个工具,专门用于Modbus 主站请求。两者的安装包在同一个官网。
Modbus Poll 的连接设置:
- 菜单“Connection”→“Connect”。
- 在弹出窗口中,选择串口(Serial Port),选择你 USB-RS485 转换器对应的 COM 口。
- 设置参数:波特率 9600,数据位 8,无校验,停止位 1。
- 从站地址(Slave ID)填 1。
- 功能码(Function)选择 03: Read Holding Registers。
- 起始地址(Address)填 0,长度填 100。
点击 OK 后,如果一切正常,你会看到寄存器列表开始周期性刷新,数值对应 PLC 中“ModbusData”DB 里的数据。
6.3 Modbus Slave 软件自身的寄存器配置
如果你要用 Modbus Slave 模拟从站来测试主站(这种方式适合先验证 PC 侧链路),配置如下:
- 菜单“Setup”→“Slave Definition”。
- Slave ID 填 1。
- Function 选择 03 Holding Register。
- Address 填 0,Quantity 填 100。
- 点击 OK。
此时 Modbus Slave 会模拟一个从站,保持寄存器数值可以手动填入,比如把第 0 个寄存器填为 1234。然后用 Modbus Poll 去读,如果读到 1234,说明 PC 串口链路是通的。
6.4 串口参数一致性对照表
| 参数 | CM1241 组态值 | Modbus Poll 设置 | Modbus Slave 设置 |
|---|---|---|---|
| 串口号 | 无 | COM3(按实际) | COM3(按实际) |
| 波特率 | 9600 | 9600 | 9600 |
| 数据位 | 8 | 8 | 8 |
| 校验位 | None | None | None |
| 停止位 | 1 | 1 | 1 |
| 从站地址 | 1 | 1 | 1 |
7. 联调测试与数据验证
7.1 在 PLC 中写入测试数据
在 OB1 中加一段赋值的逻辑,把固定值写入保持寄存器前几个地址,例如:
// 网络3:测试数据写入 "ModbusData".HoldReg[0] := 100; "ModbusData".HoldReg[1] := 200; "ModbusData".HoldReg[2] := 300;下载程序,监控变量表确认这三个值已经写入。
7.2 使用 Modbus Poll 读取数据
打开 Modbus Poll,按照 6.2 节配置连接。如果一切正常,你会看到:
| 地址 | 值 |
|---|---|
| 0 | 100 |
| 1 | 200 |
| 2 | 300 |
| 3~99 | 0 |
这时候说明 PLC 作为 Modbus 从站已经正常工作,PC 主站可以成功读取保持寄存器。
7.3 写操作测试
在 Modbus Poll 中切换到写保持寄存器功能(功能码 06 写单个寄存器或 10 写多个寄存器)。
例如:向地址 5 写入值 8888,然后回到 PLC 监控表,查看“ModbusData”.HoldReg[5] 是否为 8888。如果是,说明从站写功能也正常。
这里需要确认 PLC 程序中 MB_SLAVE 的 MB_MODE 参数是否为 1。如果 MB_MODE 为 0,则主站的写请求会被拒绝。
7.4 使用串口调试助手验证帧
如果你怀疑 PC 软件和 PLC 之间的通信帧有问题,可以用串口调试助手代替 Modbus Poll,手动发送 RTU 帧。
例如,读取从站 1 保持寄存器起始地址 0 共 3 个寄存器,请求帧为:
01 03 00 00 00 03 05 CBCRC 校验码是 05 CB(低字节在前),你可以用网上的 CRC16-Modbus 计算工具算。
如果 PLC 返回的响应帧类似:
01 03 06 00 64 00 C8 01 2C 41 8A解释:
- 01:从站地址
- 03:功能码
- 06:数据字节数(2 字节 × 3 个寄存器)
- 00 64:十六进制 100
- 00 C8:十六进制 200
- 01 2C:十六进制 300
- 41 8A:CRC 校验
这样就能确认底层通信帧是否正确。
8. 常见问题与排查思路
8.1 通信超时,Modbus Poll 一直显示 Timeout
这是最常见的故障,可能原因按概率排序如下:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 通信超时 | 接线错误(A/B 接反) | 交换 A/B 线再次测试 |
| 通信超时 | 串口参数不一致 | 核对波特率、校验位、停止位 |
| 通信超时 | COM 口选择错误 | 在设备管理器中确认 USB 转串口的 COM 号 |
| 通信超时 | CM1241 协议未设为 Modbus | 检查模块端口组态 |
| 通信超时 | 程序中未调用 MB_SLAVE | 检查 OB1 程序 |
| 通信超时 | 从站地址不一致 | 检查 MB_ADDR 和软件中的 Slave ID |
| 偶发超时 | RS485 缺少终端电阻 | 两端并联 120Ω 电阻 |
| 偶发超时 | 干扰导致 CRC 错误 | 使用屏蔽双绞线,屏蔽层单端接地 |
8.2 MB_COMM_LOAD 的 STATUS 报错
常见错误代码:
- 0x8180:参数错误或端口不支持。
- 0x8181:指定端口不存在。
- 0x8183:组态错误,端口的协议不是 Modbus。
- 0x8185:波特率、校验等参数不被支持。
优先检查 CM1241 的硬件标识符是否填错。硬件标识符在设备组态中查看,不要在程序中凭猜测填写。
8.3 MB_SLAVE 的 STATUS 报错
- 0x8090:MB_ADDR 超出范围(1~247)。
- 0x8091:MB_MODE 无效。
- 0x8092:MB_LEN 超出范围。
- 0x8093:MB_HOLD_REG 或 MB_DATA_PTR 无效,常见原因是 DB 启用了优化块访问。
遇到 0x8093,回去取消 DB 的“优化块访问”,重新编译并下载。
8.4 读到的数据全是 0
- 检查 MB_HOLD_REG 是否指向保持寄存器数组的首地址。
- 检查 PLC 程序中是否向这个数组写入过数据(可能是 0 正常,但没有数据更新)。
- 确认读取的功能码地址对应关系。Modbus Poll 中 Address 0 对应 PLC 数组的第一个元素 HoldReg[0]。
8.5 使用 USB-RS485 转换器时的供电问题
有些 USB-RS485 转换器直接从 USB 口取电,带负载能力差。如果连接距离较长或现场干扰大,会出现通信时好时坏。建议选用带隔离的 USB-RS485 转换器,比如周立功、宇泰等品牌,价格不高但稳定性好很多。
8.6 排查流程总结
如果通信失败,按这个顺序排查:
- 确认 USB 转串口驱动安装正常,设备管理器里 COM 口存在。
- 用 Modbus Slave 软件先模拟从站,用 Modbus Poll 读它。如果读不到,问题在 PC 串口链路或参数设置,与 PLC 无关。
- 用串口调试助手自发自收(回环测试),确认 USB-RS485 转换器是否正常。
- 检查 CM1241 与转换器的接线,尝试对调 A/B。
- 查看 PLC 程序中 MB_COMM_LOAD 的 STATUS 是否为 0(无错误)。
- 查看 MB_SLAVE 的 STATUS 是否为 0。
- 核对 TIA Portal 端口组态与 PC 软件参数是否完全一致。
9. 最佳实践与工程建议
9.1 数据区设计与映射规范
在真实项目中,建议不要把保持寄存器直接暴露整个 DB。更规范的做法是:
- 定义接口 DB,专门用于 Modbus 通信映射。
- 使用中间变量转发,将内部逻辑数据与通信数据解耦。
- 每个寄存器做好注释,建立寄存器地址映射表,方便维护。
例如:
保持寄存器 40001:设备启停状态 保持寄存器 40002:当前温度值(0.1℃) 保持寄存器 40003:设定温度值(0.1℃) 保持寄存器 40004~40010:预留9.2 关于安全边界
如果 PLC 作为从站,允许上位机写入寄存器,必须慎重评估写入风险。建议明确标注哪些寄存器允许写、哪些只允许读,并在 PLC 程序中增加写入范围检查和限幅。
在某些情况下,上位机误写可能导致设备误动作。从站程序中可以对写入值进行合法性校验,超出范围则拒绝写入或写入安全值。
9.3 异常处理与状态监控
不要只调用 MB_SLAVE 而不看错误状态。建议在程序中记录通信故障次数、最后一次错误状态、最近通信时间戳,上传到 HMI 或 SCADA 显示。这样可以快速定位通信中断时段,便于分析现场干扰或设备故障。
一个简单做法:每次 MB_SLAVE 的 NDR 输出为真时,记录一个时间戳到 DB,并清零通信故障计数器。如果 ERROR 输出为真,故障计数器加 1,同时保存 STATUS 值。
9.4 通信参数选择建议
Modbus RTU 在 9600 波特率下通信距离理论可达 1000 米左右,但实际现场建议控制在 500 米以内。波特率越高,抗干扰能力越差。在满足实时性要求的前提下,尽量选择较低的波特率。
校验方式优先选择无校验(None)或偶校验(Even),避免使用奇校验。某些老设备只支持偶校验,这时 PLC 侧要对应设置为偶校验。
9.5 关于“字节顺序”的坑
S7-1200 的 Modbus 指令在读取多字节寄存器时,可能涉及字节顺序问题(大字序/小字序)。在 TIA Portal 中,Modbus 指令库默认按西门子的字节序处理,即高位字节在前。如果你的上位机软件默认按低字节在前读取,就会出现数值对不上的情况(比如读到 0x1234 显示为 0x3412)。
解决方法是:在 Modbus Poll 的显示设置中调整“Word Order”为“High Word First”或“Low Word First”,或者在上位机软件中调整字节顺序。在 PLC 侧也可以通过字节交换指令(SWAP)处理。
9.6 程序版本管理
工业项目的程序修改必须留痕。每次修改后,在 OB1 或程序注释中记录修改日期、修改人、修改原因。同时将整个项目归档(TIA Portal 的“项目归档”功能),保存到版本管理目录。
10. 扩展思路与进阶方向
10.1 如果要做 S7-1200 做 Modbus 主站
如果后续项目需要 S7-1200 作为 Modbus RTU 主站,去读取现场的变频器、仪表数据,可以参考同样的思路,但需要调用 MB_MASTER 指令。该指令维护一个请求队列,通过 REG 等参数管理多个从站的轮询。主站模式下 RESP_TO 参数非常关键,需要根据现场情况调整超时时间。
10.2 与 STM32 等嵌入式设备的互联
很多工程师在调试时,会先用 Modbus Slave 软件和 STM32 联调,然后再切换到 PLC。这个思路是对的。STM32 上移植 FreeModbus 后,可以先用 Modbus Poll 验证 PC 与 STM32 的通信,再用同样的方法验证 PC 与 S7-1200 的通信。这种“先模拟从站、再接真实从站”的思路可以大大降低排错难度。
10.3 与 LabVIEW 或其他上位机通信
LabVIEW 的 VISA 串口函数也可以实现 Modbus RTU,原理雷同:配置串口参数,按 Modbus RTU 帧格式发送请求,解析响应。无论上位机是 LabVIEW、C#、Python 还是组态软件,只要遵循 Modbus RTU 协议,就可以与本文配置的 S7-1200 从站通信。
10.4 触摸屏与 PLC 的 Modbus 通信
有些第三方触摸屏(如威纶通、昆仑通态)可以通过串口与 S7-1200 做 Modbus RTU 通信,这时触摸屏作为主站,PLC 作为从站,与本文的通信方式完全一致。你只需要在触摸屏组态软件中选择“Modbus RTU Slave”或“西门子 S7-1200 (Modbus RTU)”驱动,然后配置串口参数和寄存器地址映射即可。触摸屏的地址映射通常直接映射到 PLC 的保持寄存器区,和本文的测试方法一致。
11. 结尾建议
CM1241 通信模块配合 S7-1200 做 Modbus RTU 从站,本质上并不复杂,核心就是三条:硬件接线正确、串口参数一致、指令调用无误。很多工程师卡在通信不上,往往是第一步接线问题或者参数不一致,而不是协议本身有多深奥。
如果你按本文的步骤操作,做完一次从站通信联调,你就会发现 Modbus RTU 的调试套路其实是固定的:先确认串口链路,再确认参数,最后看协议帧。这套排查思路不仅适用于西门子 PLC,也适用于其他支持 Modbus RTU 的品牌设备。建议在调试之前,先把本文的“通信参数规划表”填好,把接线端子定义打印出来贴在现场,大部分坑就能提前避开。