1. 项目概述
最近在做一个工业自动化项目,需要让西门子S7-1200 PLC通过CB 1241 RS485信号板与多台Modbus RTU从站设备通信。经过一番摸索和实践,终于实现了稳定可靠的通信。这里把整个实现过程做个详细记录,包括硬件接线、参数配置、程序编写和调试过程中踩过的坑,希望能帮到有同样需求的同行。
Modbus RTU在工业现场非常常见,很多仪表、传感器都支持这种通信协议。相比Modbus TCP,RTU版本对硬件要求更低,适合布线距离较远的场景。S7-1200本身不带RS485接口,但可以通过扩展信号板来实现,成本比通信模块低不少。
2. 硬件准备与接线
2.1 所需硬件清单
- 西门子S7-1200 PLC(型号:1214C DC/DC/DC)
- CB 1241 RS485信号板(订货号:6ES7 241-1CH32-0XB0)
- Modbus RTU从站设备(本例使用温控器)
- 标准RS485电缆(双绞屏蔽线)
- 120Ω终端电阻(长距离通信时需要)
2.2 信号板安装
CB 1241信号板直接插在PLC正面的专用插槽上,不需要额外供电。安装时注意:
- 先关闭PLC电源
- 将信号板底部的卡扣对准PLC插槽
- 轻轻按压直到听到"咔嗒"声
- 确认信号板与PLC紧密贴合无松动
2.3 RS485接线详解

关键点:
- CB 1241的TA端子接从站的B线,TB接从站的A线(线序相反!)
- 使用屏蔽双绞线,屏蔽层单端接地(PLC侧)
- 通信距离超过50米时,在总线两端各加一个120Ω终端电阻
- 避免与动力线平行走线,交叉时保持90度角
注意:很多通信问题都源于接线错误。我曾因为线序接反折腾了半天,后来发现信号板标注的TA/TB与常规理解相反。
3. 软件配置步骤
3.1 TIA Portal硬件组态
- 新建项目,添加S7-1200 PLC
- 在设备视图中右键点击PLC,选择"添加新子模块"
- 从列表中选择CB 1241(RS485)信号板
- 确认信号板出现在PLC右侧插槽位置

3.2 通信参数设置
双击添加的信号板,进入属性配置:
- 工作模式:选择"RS485"
- 传输速率:9600bps(与从站设备一致)
- 数据位:8位
- 停止位:1位
- 奇偶校验:无
- 流控制:无

实测建议:波特率不是越高越好。工业现场干扰多时,19200bps比57600bps更稳定。如果通信距离超过100米,建议降到9600bps。
4. 程序编写与调试
4.1 添加Modbus库
- 在项目树中展开"程序块"
- 右键点击"添加新块",选择"全局库"
- 从标准库中添加"Modbus_Comm_Load"和"Modbus_Master"指令块
4.2 主程序结构
pascal复制// 主程序OB1
"Modbus_Comm_Load"(REQ := TRUE,
PORT := W#16#2, // 信号板端口号
BAUD := 9600, // 波特率
PARITY := 0, // 无校验
FLOW_CTRL := 0, // 无流控
RTS_ON_DLY := 0,
RTS_OFF_DLY := 0,
RESP_TO := 1000, // 响应超时ms
DONE => "MB_Done",
ERROR => "MB_Error",
STATUS => "MB_Status");
"Modbus_Master"(REQ := "Read_Req",
MB_ADDR := 1, // 从站地址
MB_FUNC := 3, // 功能码03读保持寄存器
DATA_ADDR := 40001,// 起始地址
DATA_LEN := 2, // 读取长度
MB_DATA_PTR => "Data_Buffer",
DONE => "Read_Done",
ERROR => "Read_Error",
STATUS => "Read_Status");
4.3 关键参数说明
- PORT参数:信号板固定为W#16#2(通信模块是W#16#1)
- MB_DB参数:必须指定一个DB块作为通信缓冲区
- MODE参数:0-读取,1-写入
- DATA_ADDR:Modbus地址(注意西门子地址映射规则)

5. Modbus地址映射详解
5.1 地址转换规则
西门子PLC与Modbus地址的对应关系容易混淆,这里总结出实用对照表:
| Modbus功能码 | Modbus地址范围 | PLC存储区 | 计算示例 |
|---|---|---|---|
| 01(读线圈) | 00001-09999 | Q/M区 | Q0.0=00001 |
| 02(读离散输入) | 10001-19999 | I区 | I0.0=10001 |
| 03(读保持寄存器) | 40001-49999 | QW/MW/DB | QW0=40001 |
| 04(读输入寄存器) | 30001-39999 | IW区 | IW0=30001 |
5.2 DB块特殊处理
数据块(DB)地址需要特殊计算:
code复制Modbus地址 = (DB号 × 16384) + 字节偏移 + 1
例如:
- DB1.DBW0 → 40001 + (1×16384) = 56385
- DB2.DBW10 → 40001 + (2×16384) + 10/2 = 90006
经验:建议使用DB块存储Modbus数据,方便管理。新建DB时勾选"优化的块访问"可以提高效率。
6. Modbus RTU协议深度解析
6.1 通信帧结构
典型请求帧(十六进制):
code复制[地址][功能码][起始地址Hi][起始地址Lo][数量Hi][数量Lo][CRC Lo][CRC Hi]
示例:读取从站1的40001-40002寄存器
code复制01 03 00 00 00 02 C4 0B
6.2 CRC校验计算
CRC-16/Modbus算法步骤:
- 预置0xFFFF寄存器
- 对每个字节与寄存器低字节异或
- 右移寄存器,若移出位为1则与0xA001异或
- 重复8次得到最终CRC值
PLC实现代码:
pascal复制FUNCTION "CRC16" : WORD
VAR_INPUT
pData : POINTER TO BYTE;
iLength : INT;
END_VAR
VAR_TEMP
i : INT;
j : INT;
wCRC : WORD := 16#FFFF;
bTemp : BYTE;
END_VAR
BEGIN
FOR i := 0 TO iLength-1 DO
wCRC := wCRC XOR WORD_TO_INT(pData^);
pData := pData + 1;
FOR j := 1 TO 8 DO
IF (wCRC AND 16#0001) <> 0 THEN
wCRC := SHR(wCRC,1) XOR 16#A001;
ELSE
wCRC := SHR(wCRC,1);
END_IF;
END_FOR;
END_FOR;
"CRC16" := wCRC;
END_FUNCTION
7. 常见问题排查指南
7.1 通信失败排查步骤
- 检查物理连接
- 测量A-B线间电压(空闲时应为0.2-0.5V)
- 确认终端电阻是否必要
- 验证参数一致性
- 波特率、数据位、校验位
- 从站地址是否正确
- 监控通信数据
- 用串口调试工具抓取原始数据
- 对比请求/响应帧格式
7.2 典型错误代码
| 状态码 | 含义 | 解决方案 |
|---|---|---|
| 16#8181 | 端口忙 | 增加请求间隔时间 |
| 16#8201 | 从站无响应 | 检查从站电源和地址 |
| 16#8202 | 接收超时 | 调整RESP_TO参数 |
| 16#8203 | CRC错误 | 检查电缆质量和终端电阻 |
7.3 性能优化建议
- 合理设置轮询间隔,避免总线拥堵
- 批量读取数据(最大长度125字)
- 使用背景数据块减少扫描周期影响
- 关键数据添加超时监控逻辑
8. 项目实战技巧
8.1 多从站管理方案
当需要连接多个从站时:
- 为每个从站创建独立的MB_MASTER指令
- 使用轮询方式依次访问
- 添加从站离线检测机制(连续3次失败判定离线)
示例轮询程序:
pascal复制IF "Modbus_Cycle" THEN
CASE "Slave_Index" OF
0: // 读取从站1
"Read_Req" := TRUE;
"MB_ADDR" := 1;
IF "Read_Done" THEN
"Slave_Index" := 1;
"Read_Req" := FALSE;
END_IF;
1: // 读取从站2
"Read_Req" := TRUE;
"MB_ADDR" := 2;
IF "Read_Done" THEN
"Slave_Index" := 0;
"Read_Req" := FALSE;
END_IF;
END_CASE;
END_IF;
8.2 数据转换处理
Modbus寄存器通常存储原始数据,需要转换:
- 16位整数:直接读取
- 32位浮点数:使用UNION结构转换
pascal复制TYPE "Float_DWORD" :
UNION
"RealValue" : REAL;
"DWordValue" : DWORD;
END_UNION
END_TYPE
8.3 安全防护措施
- 添加通信看门狗(超时复位)
- 关键数据范围校验
- 异常状态记录到诊断缓冲区
- 重要参数写保护
经过这个项目的实践,我发现西门子1200通过信号板实现Modbus RTU通信完全可行,成本比通信模块低很多。最关键的是接线要正确,参数设置要与从站完全一致。遇到通信问题时,建议先用Modbus调试工具单独测试从站,排除硬件问题后再排查PLC程序。
