(十七)西门子S7-200 SMART PLC Modbus通讯功能介绍 GitHub 项目地址https://github.com/lidecong133/YModbusS7-200 SMART 在小型设备、单机设备、改造项目里很常见。现场经常会遇到这种问题“我有一台 200 SMART能不能用 Modbus 和上位机、变频器、伺服、仪表通讯”答案是可以但要先分清方向。S7-200 SMART 的 Modbus 通讯最常见的是通过 RS485 做 Modbus RTU。它既可以作为主站去读写外部从站也可以作为从站被上位机或触摸屏读取。但它不是“只要 PLC 在线就等于 Modbus 能通”。PLC 端必须配置对应的 Modbus 库、通讯端口、站号、波特率、校验位、保持寄存器区等内容。下面按主站、从站、地址映射和 YModbus 联调几个角度把这个功能讲清楚。先分清谁是主站谁是从站Modbus 通讯里一定有主动发请求的一方也有被动响应的一方。在 S7-200 SMART 项目里常见有两种结构。第一种S7-200 SMART 当 Modbus 主站。比如 PLC 通过 RS485 去控制变频器、伺服驱动器、温控表、称重仪表。这时 PLC 主动发请求读变频器状态字写变频器控制字写速度设定值读仪表当前值写仪表参数第二种S7-200 SMART 当 Modbus 从站。比如上位机、触摸屏、边缘网关、采集程序来读取 PLC 数据。这时 YModbus 或其他主站工具主动读 PLC读 PLC 的 Q 输出状态读 PLC 的 I 输入状态读模拟量读写 V 区映射出来的保持寄存器这两个方向完全不一样。如果 PLC 当主站YModbus 不能也当主站直接去跟同一个从站抢通讯。如果 YModbus 要读 PLCPLC 端就要配置成 Modbus 从站或 Modbus TCP Server 这一类角色。S7-200 SMART做Modbus RTU主站S7-200 SMART 做 RTU 主站时常见使用 Modbus 主站库。主站侧通常会用到MBUS_CTRLMBUS_MSGMBUS_CTRL用来初始化和管理 Modbus 通讯端口。MBUS_MSG用来执行具体读写请求。比如 S7-200 SMART 控制一台变频器PLC 会通过MBUS_MSG写控制字、写频率设定再通过另一个请求读状态字和实际速度。现场要注意一件事不要多个MBUS_MSG同时触发。更稳的做法是轮询。第一个请求完成以后再触发第二个请求第二个请求完成以后再触发第三个请求。每个请求看Done和Error不要所有读写块一起使能。很多人第一次写程序会把几个MBUS_MSG都接到常开位上。结果就是通讯乱、错误码乱、偶尔能通偶尔不通。我的习惯是用一个步骤号或计数器控制请求顺序步骤 0读状态字 步骤 1读实际速度 步骤 2写控制字 步骤 3写设定值 完成后回到步骤 0这样现场看起来很清楚也方便定位到底是哪一步报错。主站常见参数S7-200 SMART 做 Modbus 主站时最容易配错的是这些参数参数说明Mode是否启用 Modbus 协议功能Baud波特率Parity校验方式Port使用 CPU 自带 RS485 口还是 CM01 信号板Timeout等待从站响应的时间Slave目标从站地址RW读还是写Count读写的数据个数DataPtr数据缓冲区指针波特率、校验位、从站地址必须和对方设备一致。Timeout 不要一开始设太短。变频器、伺服、仪表响应慢一点或者总线上设备多一点太短就会误判超时。如果从站完全没响应不要只看程序。先查 RS485 A/B 线、终端电阻、站号、波特率、校验位。S7-200 SMART做Modbus RTU从站S7-200 SMART 做 RTU 从站时常见使用从站库。从站侧通常会用到MBUS_INITMBUS_SLAVEMBUS_INIT用来初始化从站参数。MBUS_SLAVE用来在扫描周期里持续处理主站请求。这时 YModbus 可以作为主站来读 S7-200 SMART。比如ymodbusread-holding-registers--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity none--stop-bitsone--slave-id 1--address 0--quantity 10如果能读到说明 YModbus 主站和 S7-200 SMART 从站通讯正常。如果读不到就先看 PLC 的MBUS_INIT参数站号、波特率、校验位、端口、保持寄存器区起始地址和长度。从站地址怎么映射S7-200 SMART 做 Modbus RTU 从站时地址映射很重要。常见映射思路是Modbus地址类型S7-200 SMART数据区00001开始Q 输出点10001开始I 输入点30001开始AI 模拟量输入40001开始V 存储区映射出来的保持寄存器这里最容易错的是保持寄存器。保持寄存器不是自动等于所有 V 区。从站库里通常要指定保持寄存器区的起始地址比如从某个VB开始。这个地址作为 Holding Register 的缓冲区。举个例子。如果 PLC 端把保持寄存器区设置为从VB1100开始那么 Modbus 保持寄存器40001通常对应这个缓冲区的第一个字也就是VW1100。YModbus 里读保持寄存器地址0ushort[]valuesawaitclient.ReadHoldingRegistersAsync(0,10);对应的就是 Modbus 显示地址40001开始的 10 个保持寄存器。不要把 PLC 里的VW100直接想成 Modbus 地址100。中间还有“保持寄存器缓冲区从哪里开始”这个映射关系。S7-200 SMART从站支持哪些常用功能码作为 Modbus RTU 从站时常见会用这些功能码功能码作用常见访问对象01读线圈Q 输出点02读离散输入I 输入点03读保持寄存器V 区保持寄存器缓冲区04读输入寄存器AI 模拟量05写单个线圈Q 输出点06写单个保持寄存器V 区保持寄存器缓冲区15写多个线圈Q 输出点16写多个保持寄存器V 区保持寄存器缓冲区实际支持范围和限制要以你使用的 S7-200 SMART 系统手册、库版本和 STEP 7-Micro/WIN SMART 帮助为准。比如批量读写数量、Q 点写入是否被用户程序覆盖、保持寄存器缓冲区大小都不是上位机单方面能决定的。和YModbus怎么配合如果 S7-200 SMART 已经配置成 Modbus RTU 从站YModbus 作为主站可以这样读usingSystem.IO.Ports;usingYModbus.Clients;usingYModbus.Serial;usingSerialPortportnew(COM3){BaudRate9600,DataBits8,ParityParity.None,StopBitsStopBits.One,ReadTimeout3000,WriteTimeout3000};port.Open();awaitusingModbusClientclientModbusSerialClientFactory.CreateRtu(slaveId:1,serialPort:port,leaveOpen:true);ushort[]valuesawaitclient.ReadHoldingRegistersAsync(0,10);用 CLI 先验证更方便ymodbusread-holding-registers--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity none--stop-bitsone--slave-id 1--address 0--quantity 10如果 PLC 端配置的是偶校验就要改--parity even如果 PLC 站号不是 1就改--slave-id。先把最小读取跑通再去写上位机程序。Modbus TCP要单独确认S7-200 SMART 不同代际、不同固件和不同软件库对 Modbus TCP 的支持方式不完全一样。有些资料里会看到MB_CLIENT、MB_SERVER这一类 Modbus TCP 指令但不要把 S7-1200 / S7-1500 的用法直接搬到 S7-200 SMART 上。比较稳妥的做法是看你手里的 CPU 型号和固件版本看 STEP 7-Micro/WIN SMART 里是否有对应 Modbus TCP 指令或库看官方系统手册对应章节先用一个固定保持寄存器做最小测试如果 S7-200 SMART 已经作为 Modbus TCP Server 开起来YModbus TCP 读取方式就是awaitusingModbusClientclientawaitModbusClientFactory.CreateTcpAsync(host:192.168.1.10,port:502,unitId:1);ushort[]valuesawaitclient.ReadHoldingRegistersAsync(0,10);CLI 验证ymodbusread-holding-registers--host 192.168.1.10--port 502--unit-id 1--address 0--quantity 10如果 TCP 端口不通先不要查寄存器。先确认 PLC 端 Modbus TCP Server 是否真的启用、端口是否开放、防火墙或网络是否拦截。一个实际调试例子假设 PLC 程序员说“我把 10 个数据放在 V 区给你按 Modbus 保持寄存器读。”这句话还不够。你要继续问S7-200 SMART 是 RTU 从站还是 TCP Server站号是多少RTU 参数是多少保持寄存器缓冲区从哪个 VB 开始Modbus 地址从40001开始吗这 10 个值是什么类型有没有倍率有没有 32 位或浮点数如果对方说保持寄存器从VB1100开始第一个值是VW1100 1234站号是1串口是9600,N,8,1。那你就可以先用 CLI 读ymodbusread-holding-registers--transport rtu--serial-port COM3--baud-rate 9600--data-bits 8--parity none--stop-bitsone--slave-id 1--address 0--quantity 1读到1234说明基本链路和映射都对。如果读不到再按顺序查串口、站号、校验位、MBUS_INIT、MBUS_SLAVE、保持寄存器缓冲区、库内存分配。库内存分配也会影响通讯S7-200 SMART 使用 Modbus 库时库本身需要占用 V 存储区。保持寄存器缓冲区也会占用 V 存储区。这两个区域不能重叠。如果重叠程序可能能编译但运行时通讯异常、数据错乱、错误码莫名其妙。所以分配库内存时不要随便从VB0开始一路占用。最好规划清楚库使用区例如 VB0 ~ VB800 保持寄存器区例如 VB1100 ~ VB3100 用户变量区避开以上区域具体地址按你的项目和库提示来不要照抄。常见坑S7-200 SMART Modbus 通讯里我最常见到这些问题PLC 端没调用MBUS_SLAVE上位机当然读不到MBUS_INIT只初始化了但后续没有持续处理请求波特率和校验位与上位机不一致SlaveId 填错RS485 A/B 接反保持寄存器缓冲区和库内存重叠把40001当成 YModbus 地址40001把 PLC 内部VW100当成 Modbus 地址100多个MBUS_MSG同时触发主站通讯混乱Q 点被 Modbus 写入后又被 PLC 用户程序覆盖这些问题都很普通但每一个都能让现场调试卡很久。我建议的联调顺序如果让我接一台 S7-200 SMART我会这样做先确认 PLC 是 Modbus 主站还是从站如果 YModbus 要读 PLC确认 PLC 端从站库已经运行RTU 先确认串口参数和站号让 PLC 放一个固定值到第一个保持寄存器用 CLI 读地址0数量1读通后再读一段再处理int32、float、倍率、字节序最后才考虑写入写入前一定要确认这个寄存器是不是允许写。尤其是写 Q 输出点或控制字时不要拿真实设备乱试。到这里S7-200 SMART 的 Modbus 通讯功能不难但它有几个关键点主站用MBUS_CTRL/MBUS_MSG从站用MBUS_INIT/MBUS_SLAVERTU 参数必须一致保持寄存器通常映射到指定 V 区YModbus 里的地址是从0开始的协议地址多个MBUS_MSG要轮询执行不要同时触发库内存区和保持寄存器区不要重叠这些弄清楚S7-200 SMART 和 YModbus 配合起来就比较顺。参考资料SiemensS7-200 SMART Modbus RTU CommunicationSiemensS7-200 SMART 与 G120 变频器 MODBUS RTU 通讯控制SiemensS7-200 Smart 通过 Modbus 通信实现 V90 的速度控制