第三章:PLC编程实战——西门子S7-1200与三菱FX5U的Modbus库调用,主站从站配置

好,咱们直接进入正题。这一章,我带你手把手把两台PLC通过Modbus连起来。一台是西门子S7-1200,一台是三菱FX5U。说白了,就是让它们俩能互相读懂对方的数据。

你可能会问:这两家PLC的编程软件都不一样,怎么玩?别急,Modbus协议就是它们的“共同语言”。我当年第一次做这个项目时,也心里没底。但摸清楚套路后,发现其实就那么回事。

核心思路:S7-1200做主站,主动发请求。FX5U做从站,被动响应。主站问什么,从站就答什么。

3.1 硬件连接与准备工作

动手之前,先把家伙事儿备齐。你需要:

  • 一台西门子S7-1200(我用的1214C,其他型号也行)
  • 一台三菱FX5U(带以太网口的版本)
  • 一根普通网线,直连或者通过交换机都行
  • TIA Portal V16及以上版本(博途)
  • GX Works3(三菱的编程软件)

嗯,这里要注意:两台PLC的IP地址必须在同一个网段。比如S7-1200设成192.168.1.10,FX5U设成192.168.1.20。我见过有人把IP设成不同网段,折腾半天连不上,最后发现是这低级错误。

3.2 三菱FX5U作为Modbus从站的配置

咱们先从从站开始。FX5U天生就支持Modbus TCP从站,但需要手动开启。

打开GX Works3,按以下步骤操作:

  1. 在导航栏找到「参数」→「FX5UCPU」→「模块参数」→「以太网端口」
  2. 双击打开,找到「通信协议支持」选项
  3. 勾选「Modbus TCP」协议
  4. 设置端口号,默认502,我建议你别改
  5. 设置从站站号,比如设成1

写参数的时候,记得把配置下载到PLC里,然后断电重启。为什么?因为以太网参数必须重启才能生效。我刚开始做时忘了这步,参数写进去没反应,还以为是PLC坏了。

小技巧:FX5U的Modbus从站默认支持的功能码有:01(读线圈)、02(读离散输入)、03(读保持寄存器)、04(读输入寄存器)、05(写单个线圈)、06(写单个寄存器)、15(写多个线圈)、16(写多个寄存器)。够用了。

3.3 西门子S7-1200作为Modbus主站的配置

接下来是重头戏——S7-1200做主站。博途里有个现成的库叫「Modbus TCP」,直接调用就行。

我个人习惯先把库文件加载进来。在博途的「库」面板里,找到「通信」→「Modbus TCP」→「MB_CLIENT」。这个就是主站功能块。

拖到程序里后,你会看到一堆引脚。别慌,核心的就这几个:

引脚 数据类型 说明
REQ BOOL 上升沿触发请求
MB_MODE USINT 0=读,1=写
MB_DATA_ADDR UDINT 从站的寄存器地址
MB_DATA_LEN UINT 读取/写入的数据长度
MB_DATA_PTR VARIANT 指向本地数据区的指针
CONNECT TCON_IP_v4 连接参数,包含从站IP和端口

写代码时,我建议你用一个定时器循环触发REQ。比如每500毫秒发一次请求。别太快,也别太慢。太快了从站扛不住,太慢了实时性差。

// 主站调用示例(SCL语言)
"MB_CLIENT_DB".MB_CLIENT(
    REQ := "Clock_500ms",
    MB_MODE := 0,  // 读模式
    MB_DATA_ADDR := 40001,  // 从站的保持寄存器起始地址
    MB_DATA_LEN := 10,  // 读取10个字
    MB_DATA_PTR := "Data_From_Slave",  // 本地接收数组
    CONNECT := "Connection_FX5U",
    DONE => "Read_Done",
    ERROR => "Read_Error",
    STATUS => "Read_Status"
);

注意:Modbus地址映射有个坑。三菱的保持寄存器地址从40001开始,但实际报文里用的是0x0000。也就是说,你在博途里填MB_DATA_ADDR时,如果要从40001开始读,就填40001。但有些库要求填0。我建议你查一下具体库的文档,或者先试读一个地址看看返回值对不对。

3.4 主从站联调实战

两边都配好了,怎么知道通没通?我的做法是:先写一个简单的读写测试。

在FX5U里,把D100到D109这10个寄存器写入一些固定值,比如1,2,3,4,5...然后在S7-1200里读取这10个寄存器。如果读到的值跟写入的一致,说明通信正常。

我曾经遇到过一个情况:读回来的数据全是0。检查了半天,发现是FX5U的Modbus从站功能没启用。嗯,这种低级错误犯过一次就不会再犯了。

如果通信失败,按这个顺序排查:

  1. 网线插好了吗?指示灯亮不亮?
  2. IP地址能ping通吗?
  3. 从站的Modbus功能开启了吗?
  4. 主站的连接参数(IP、端口)填对了吗?
  5. 寄存器地址和数据类型匹配吗?

你想想看,大部分问题都出在这几个环节。尤其是地址匹配,三菱和西门子的数据存储方式不一样,一个是大端,一个是小端。读单个字没问题,读32位浮点数时就要注意字节顺序了。

3.5 知识体系与核心逻辑

下面这张图,是我自己总结的Modbus主从通信的完整流程。你看一眼就明白了。

S7-1200 主站 MB_CLIENT 功能块 FX5U 从站 Modbus TCP 服务 Modbus 请求 功能码 + 地址 + 数据 Modbus 响应 数据或异常码 本地数据区 DB块 / M区 / 数组 从站数据区 D寄存器 / M线圈 Modbus TCP 主从通信架构 S7-1200 主站 ←→ FX5U 从站

这张图把整个通信链路拆成了三层:主站应用层、网络传输层、从站应用层。你写程序时,脑子里要有这个分层概念。哪一层出问题,就针对那一层去排查。

3.6 避坑指南与经验总结

最后,我把自己踩过的坑整理一下,你遇到了直接对照:

  • 连接超时:检查防火墙,Windows防火墙有时会拦截502端口。我有一回就是被这玩意儿坑了半小时。
  • 数据错位:三菱的D寄存器是16位,西门子的Word也是16位。但如果你读32位浮点数,记得用SWAP指令交换字节顺序。
  • 通信中断:FX5U的Modbus从站服务在CPU停机时会停止。确保从站处于RUN状态。
  • 地址越界:FX5U的保持寄存器范围是D0到D7999,别读到不存在的地址去。

我曾经在一个项目里,主站读从站的温度数据,读出来一直是65535。查了半天,发现是从站的寄存器地址写错了,多写了一个0。这种细节,真是让人又气又笑。

好了,这一章的内容就到这儿。你按照上面的步骤,把两台PLC的Modbus通信调通,后面章节的实战就好办了。


公众号:蓝海资料掘金营,微信deep3321