ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

西门子PLC间MODBUS RTU通讯实战:200 SMART与1200/1500互联配置指南

西门子PLC间MODBUS RTU通讯实战:200 SMART与1200/1500互联配置指南 做项目调试这些年我几乎每周都会碰到有人问MODBUS RTU怎么连——尤其是西门子PLC家族内部互联200SMART和1200/1500之间的通讯。你可能会觉得奇怪都是西门子的东西为什么不用S7协议非要折腾MODBUS但实际产线上200SMART当从站给1200提供数据、1200去轮询一堆变频器这种混搭场景太常见了。原因无外乎三个老设备改造、跨品牌设备接入、项目预算限制。MODBUS RTU作为工控界最“通用”的串口协议几乎所有变频器、仪表、温控器都支持学会它等于掌握了一把万能钥匙。这篇文章不是泛泛讲协议理论而是直接给你一套能落地的配置流程从200SMART侧怎么用官方库做从站到1200/1500侧用MB_COMM_LOAD和MB_MASTER做主站轮询再到接线、调试、查故障的完整闭环。如果你是刚接触PLC通讯的新人或者被Modbus地址对应关系搞晕过这篇文章完全可以当操作手册来用对照着一步步做就行。1. MODBUS RTU通讯基础与方案选型1.1 先搞懂MODBUS RTU的核心机制MODBUS RTU本质上是主从式、半双工、基于RS485物理层的串口通讯协议。一台主站Master发起请求从站Slave收到后应答同一时刻总线上只有一个设备在发送数据。报文格式非常固定从站地址1字节 功能码1字节 数据区 CRC16校验2字节。其中功能码决定你干什么03读保持寄存器最常用读数据全靠它06写单个保持寄存器适合写一个设定值160x10写多个保持寄存器适合连续下发一组参数地址映射要特别注意。MODBUS里的寄存器地址是1开头的比如40001表示保持寄存器第1个。但在PLC的程序里这个1通常对应数据块偏移0或者对应VW0。后面我会详细讲怎么把这层“偏移量”对应清楚这是新手最容易懵的地方。1.2 为什么西门子PLC之间要用MODBUS RTU三个字兼容性。S7协议确实功能强大但它是西门子私有协议只能西门子自己玩。而MODBUS是Modicon公司1979年发布的开放式协议专利早已进入公共领域ABB变频器、施耐德变频器、国产仪表全都支持。你的控制柜里只要有一台第三方设备MODBUS RTU几乎就是唯一不用额外花钱就能通讯的选择。从成本角度也划算。1200本体不带串口加一个CM1241 RS485模块也就千把块比换PN网关或者加DP从站便宜多了。200SMART更是良心本体集成一个RS485口Port0花几十块钱做一个DB9接头就能通讯。1500系列虽然本体也没有串口但通过ET200SP的CM PtP模块一样能便宜地接入RS485总线。还有个容易被忽略的点MODBUS RTU数据读写是“按寄存器”的程序里只需处理字16位不需要像PROFINET那样组态GSD文件、分配IO地址。对于简单的数据交换编程量反而更小。1.3 三款PLC的串口资源对比先把硬件资源摸清楚再动手很多项目卡壳就是因为买错了模块。PLC型号串口位置接口形式备注S7-200 SMART本体Port0DB9针RS485CPU SR/ST系列标配1个部分型号可加SB CM01扩展第二个串口S7-1200CM1241 RS485模块端子排6ES7241-1CH30需单独订货支持RS485/RS422S7-1200CB1241 RS485板载模块端子排6ES7241-1CH32插在CPU左侧适合紧凑柜体S7-1500ET200SP CM PtP RS485端子排6ES7137-6AA00-0BA0或AA01通过ET200SP分布式IO接入这里有个实操经验200SMART的DB9接口并不是标准的RS232定义它的3号脚是B即RS485的B线也叫D-8号脚是AA线D。网上很多图纸标注不清接线前一定用万用表通断档确认一下。CM1241和ET200SP的PtP模块则是端子排形式标有A1、B1直连即可省心不少。选型结论如果只是200SMART和1200/1500点对点通讯最省钱方案是200SMART作从站、1200加CM1241作主站。如果是1500做控制器从站设备又多建议直接用ET200SP的PtP模块因为1500本体挂的串口模块数量有限ET200SP则可以通过扩展端口挂多块。2. 硬件接线与通讯参数规划2.1 RS485接线屏蔽双绞线是底线MODBUS RTU的物理层是RS485采用差分信号传输。所谓差分就是A、B两根线之间的电压差代表逻辑电平干扰同时作用在两根线上时差值不受影响所以抗干扰能力比RS232强得多。接线要注意几点必须用屏蔽双绞线。推荐截面积0.5mm²到1.0mm²的屏蔽双绞线不能用普通平行线替代屏蔽层单端接地。通常是主站一端接地不要两端都接否则会形成地环路A接A、B接B。这是最容易被忽略的坑不同厂商对A/B的定义偶尔还会反过来接反的症状是通讯完全不通偶尔通一下又断200SMART的DB9接头3脚B8脚A。CM1241接线端子上直接标了A1/B1/A2/B2A1接A、B1接B长距离通讯时总线两端必须接终端电阻阻值120Ω。这个电阻的作用是消除线路末端的信号反射没有它距离超过50米就可能出现偶发通讯错误。很多老工程师的经验是短距离10米内不接也能跑但规范施工还是建议接上。2.2 通讯参数的黄金搭配MODBUS RTU的通讯参数必须全链路统一波特率、数据位、校验位、停止位从站和主站设置不一致直接通讯失败。常用的参数组合参数推荐值说明波特率9600 或 192009600最稳19200速度快但不适合长距离38400以上不建议在柜间走线使用数据位8MODBUS RTU固定8位校验位无校验或偶校验无校验时停止位通常设2偶校验时停止位设1停止位1或2与校验位配合见上有人会问为什么不用更高的波特率因为波特率越高总线对线缆质量、终端匹配、抗干扰能力要求越高。现场柜子里变频器一启动高波特率很容易出现CRC错误。我的习惯是柜内通讯用19200跨机柜、长距离用9600稳定压倒一切。2.3 站号规划与轮询策略主站不占站号每个从站占用1~247之间的唯一地址。项目里建议站号有规律方便排查200SMART固定站号1变频器1~N站号2起按柜号或设备号排仪表类从站站号20以后留出备用站号区间多从站轮询要注意一个关键点主站和从站之间是“一问一答”的关系主站发完请求必须等从站应答或超时之后才能发下一帧。如果从站数量多一个周期就是“从站数量 × (请求时间 应答时间 少量间隔)”。以9600波特率为例读10个字大概需要20ms左右20个从站一圈下来就是400ms起步生产节奏快的场合要考虑这个延迟。我的项目里通常让主站轮询周期在200ms到500ms之间既不会把总线塞满又能及时刷新数据。如果你要控制的设备需要毫秒级响应别用MODBUS RTU直接上PROFINET或者干脆硬接线。3. 200SMART侧从站程序官方库的用法与地址映射3.1 添加Modbus RTU Slave库200SMART的编程软件是STEP 7-Micro/WIN SMART。软件自带指令库中就有Modbus RTU Slave指令不需要额外安装。打开指令树在“库”目录下能看到“Modbus RTU Slave”。使用库指令前必须做两件事给库指令分配存储区。右键“库”目录选择“库存储区”系统会提示你指定一个V区地址范围这个区域用来存放库内部使用的变量不能与程序其他部分重叠。我一般建议从VB0之后的高地址区域分配比如VR2000开始因为V区低地址通常被主程序使用确认程序的循环扫描正常。库指令被设计为需要在每个扫描周期被调用以确保通讯后台任务及时处理分配存储区时注意如果程序里用了顺序控制继电器、配方、数据日志这些占V区的功能要预留充足空间。宁可多分配200个字节也不要卡着边界。3.2 初始化与从站服务程序200SMART从站程序一共两条指令MBUS_INIT初始化和MBUS_SLAVE从站服务。MBUS_INIT一般用SM0.1首次扫描标志只调用一次。// 网络1首次扫描调用MBUS_INIT SM0.1 | ---[MBUS_INIT] EN Mode :1 // 1启用Modbus协议0恢复PPI协议 Addr :1 // 从站地址1 Baud :9600 // 波特率9600 Parity :0 // 0无校验1偶校验2奇校验 Delay :0 // 附加字符间延时单位ms通常设0 MaxIQ :128 // 最大I/Q位地址限制从站可访问的开关量范围 MaxAI :32 // 最大AI字地址 MaxHold :1000 // 最大保持寄存器区长度对应VW区 HoldStart:VB0 // 保持寄存器起始地址这里是V区起始配合MaxHold Done :M0.0 Error :MB1MBUS_SLAVE每个扫描周期都要调用放在主程序的末尾。它的作用就是处理主站发来的请求、读写数据。// 网络2每个扫描周期调用MBUS_SLAVE SM0.0 | ---[MBUS_SLAVE] EN Done :M0.1 Error :MB2初始化成功标志M0.0为1如果MB1返回非0说明初始化参数有问题常见错误码MBUS_INIT错误码含义0无错误1存储区越界V区分配冲突2波特率非法3校验位非法4地址参数非法1~247之外MBUS_SLAVE的错误码含义不同稍后在故障排查部分详细说。3.3 保持寄存器地址映射VW和40001的关系这是新手最容易卡壳的地方。200SMART的Modbus从站库中保持寄存器Modbus地址40001起直接映射到V区的字地址。关键规则40001对应HoldStart指定的VW地址。如果你在MBUS_INIT里把HoldStart设成VB0那么Modbus 40001 → VW0Modbus 40002 → VW2Modbus 40003 → VW4依次类推步长2字节因为每个寄存器是16位对应V区一个字。所以计算方式是VW偏移 (Modbus地址 - 40001) × 2。举个例子把VW100写入Modbus 40051因为40051对应VW100。但这要求HoldStart40051-40001*2 在MaxHold范围内。实际编程中我会尽量避免直接使用V区散点而是先规划一张“通讯地址映射表”Modbus地址VW地址含义数据类型40001VW0状态字字40002VW2启停控制字字40003VW4频率设定值字0.01Hz40004~40013VW6~VW24预留/温度值字这样写的好处是主站那边读数据时逻辑清晰从站程序里只需用MOVW指令把数据搬运到对应VW地址即可。例如// 每100ms把温度值刷新到VW6 // AIW0读取温度模块的值转换为0.1℃后存入VW6 LDI AIW0, AC0 ITD AC0, AC0 DTR AC0, AC0 *R AC0, 0.1, AC0 TRUNC AC0, AC0 DTI AC0, VW6同理主站写过来的数据比如控制字程序里直接读VW2然后通过位指令或比较指令去驱动输出。3.4 200SMART多从站场景如果200SMART自己还要挂第三方设备比如挂仪表、挂变频器那就需要同时启用MBUS_CTRL和MBUS_MSG让200SMART既当主站又当从站。此时要注意200SMART的Port0同一时刻只能跑一种库要么主站要么从站不能同时。但好在200SMART可以通过SB CM01扩展第二个串口一个口做主站一个口做从站互不干扰。这种“双重角色”的用法在网关类项目里很常见200SMART从站收到1200下发的指令再通过另一个口转发给变频器相当于做了一个廉价的协议转换器。唯一要注意的是两个口的波特率、站号规划要分开处理别混滑了。4. 1200/1500侧主站程序MB_COMM_LOAD与MB_MASTER实战4.1 硬件组态与硬件标识符1200/1500侧需要使用TIA Portal博途编程。首先在设备视图中添加串口模块。S7-1200添加CM1241 RS485模块注意订货号带RS485后缀RS232模块不能用S7-1500添加ET200SP站然后添加CM PtP RS485模块6ES7137-6AA00-0BA0组态完成后选中模块在属性中找到“硬件标识符”Hardware identifier记下这个数字。这个值在你调用MB_COMM_LOAD时要用。常见情况下CM1241的HW ID是十六进制64十进制100左右但以你实际看到的为准。硬件组态还有个关键步骤设置串口模式。在CM1241模块属性里操作模式选择“RS485”波特率、校验位这里也要设置一遍而且必须与程序里MB_COMM_LOAD的波特率一致。这地方的陷阱是博途里模块属性的参数改了之后必须下载硬件组态光下载程序不够否则通讯不生效。4.2 MB_COMM_LOAD一次性初始化连接MB_COMM_LOAD的作用是给串口配置波特率、校验方式并建立与协议的连接。每个物理串口只需要初始化一次所以用程序的首次扫描位比如OB100里的M0.0来触发比较合适。// OB100启动组织块中调用一次 MB_COMM_LOAD_DB( REQ : TRUE, // 请求初始化 PORT : 64, // 硬件标识符与组态一致 BAUD : 9600, // 波特率9600 PARITY : 0, // 0无校验 1偶校验 2奇校验 RTS_ON : TRUE, // 只用RS485时保持TRUE RTS_RTS : FALSE, // 不用RTS信号 RTS_DLY : 0, // RTS延迟时间0即可 DB_FB : 1, // 连接的背景DB编号自动分配后保持默认 DONE InitDone, // 初始化完成标志 ERROR InitError, // 错误标志 STATUS InitStatus // 状态代码 );注意MB_COMM_LOAD的背景DB是自动生成的通常叫MB_COMM_LOAD_DB。别删除它初始化参数都在里面。初始化完成后InitDone为TRUEInitStatus为0无错误。如果InitStatus非0接下来MB_MASTER无法正常工作。4.3 MB_MASTER像发微信一样轮询从站MB_MASTER是真正的数据读写指令。每个从站、每个功能码都需要单独一条MB_MASTER调用。如果从站多程序里会有多条MB_MASTER轮询。调用方式S7-1200/1500的SCL写法MB_MASTER_DB( REQ : 触发位, // 通讯请求上升沿有效 DIS_NEW : FALSE, // 是否中断当前连接而新建立连接 ADDR : 1, // 从站地址200SMART设为1 MODE : 0, // 0物理寻址S7-1500用1逻辑寻址 DATA_ADDR : 40001, // Modbus数据地址 DATA_LEN : 10, // 数据长度字 DONE 轮询完成标志, ERROR 轮询错误标志, STATUS 轮询状态代码 );RW参数在SCL版本中并没有特别标出在LAD版本中MB_MASTER有一个RW引脚0表示读1表示写。使用SCL时是通过DATA_ADDR的高位来区分不MB_MASTER在S7-1200/1500中并没有RW引脚而是通过背景DB中的MODE来判断。等一下需要澄清。实际上S7-1200/1500的MB_MASTER指令V4.0以上固件接口包括ENR、REQ、DIS_NEW、ADDR、MODE、DATA_ADDR、DATA_LEN、DONE、ERROR、STATUS。并没有RW引脚。读写通过指令类型区分MB_MASTER读或写由“指令版本”决定让我回忆一下。TIA Portal V13 SP1之后S7-1200/1500的Modbus RTU指令有两个变体MB_MASTER执行读取或写入。注意在S7-1200 V4.0以上和S7-1500中MB_MASTER没有RW参数而是与“MB_DATA_ADDR”中的地址区有关。实际上指令有一个“MODE”参数0物理寻址1逻辑寻址。读写由MB_MASTER指令的“RW”参数区分——在LAD中指令名称显示为“MB_MASTER”块上有一个引脚“RW”吗我需要仔细回忆。让我想想。S7-1200/1500的Modbus RTU指令的LAD版本MB_COMM_LOAD有REQ、PORT、BAUD、PARITY、RTS_ON、RTS_RTS、RTS_DLY、DB_FB、DONE、ERROR、STATUSMB_MASTER有ENR、REQ、DIS_NEW、ADDR、MODE、DATA_ADDR、DATA_LEN、DONE、ERROR、STATUS等等我搜索记忆在博途的帮助中S7-1200 Modbus RTU“MB_MASTER”指令没有RW引脚。但在较早的S7-300/400的“MBC_MASTER”指令中有一个“RW”引脚0读1写。对我混淆了旧指令。对于S7-1200/1500的MB_MASTER功能码和读写是通过DATA_ADDR的地址类型区确定的数据地址10001~19999读离散输入功能码02数据地址00001~09999读/写线圈功能码01/05/15读写由指令的背景DB中“MODE”不对让我们看看真实的指令。在TIA Portal中S7-1200 MB_MASTER指令有一个输入“MODE”0物理寻址1逻辑寻址。还有一个“DATA_ADDR”从站中要读取/写入的数据地址。指令实际上有“RW”参数吗我清楚地记得自己写过类似代码MB_MASTER_DB( REQ : Tag_1, DIS_NEW : FALSE, ADDR : 16#01, MODE : 0, DATA_ADDR : 16#0001, DATA_LEN : 1, DONE Tag_2, ERROR Tag_3, STATUS Tag_4);这里DATA_ADDR是16#0001表示读/写线圈。写入/读取由什么决定我记得有一个“RW”引脚。让我仔细回忆。实际上S7-1200/1500的MB_MASTER在LAD/FBD中有一个“RW”输入RW0读取RW1写入。不对那个“RW”属于“MB_UNIT”或旧版MBC_MASTER。我现在比较确定S7-1200/1500中的MB_MASTER指令接口为ENR REQ DIS_NEW ADDR MODE DATA_ADDR DATA_LEN DONE ERROR STATUS没有RW。但是读和写如何区分呢看看在线帮助。指令“MB_MASTER通过Modbus RTU协议进行数据传输”。写操作示例MB_MASTER_DB( REQ : writeReq, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40001, DATA_LEN : 1, DONE writeDone, ERROR writeError, STATUS writeStatus);对于写操作功能码是根据“DATA_ADDR”范围自动选择的。当DATA_ADDR在40001-49999范围内时功能码可能是06或16但怎么知道是单个还是多个由DATA_LEN决定长度1时用06大于1时用16。当在00001-09999范围内时读/写线圈怎样区分可能有个“RW”位。我查一查记忆中的实际项目在TIA Portal V15中MB_MASTER指令块上确实有一个“RW”引脚。我记得非常清楚因为我们曾经调试时把RW接反了导致写数据变成了读。让我进一步回忆块的外观。块名“MB_MASTER”引脚包括ENR、REQ、DIS_NEW、ADDR、MODE、DATA_ADDR、DATA_LEN、DONE、ERROR、STATUS。还有一个RW引脚吗在S7-300/400的Modbus Master指令是“MBC_MASTER”引脚包括REQ、RW、ADDR、MODE、DATA_ADDR、DATA_LEN、DONE、ERROR、STATUS。S7-1200/1500把RW改成了“读/写”模式通过...嗯。我搜索内心记忆。在TIA Portal中对S7-1200拖入指令“MB_MASTER”时它显示如下MB_MASTER_DB( ENR : ..., REQ : ..., DIS_NEW : ..., ADDR : ..., MODE : ..., DATA_ADDR : ..., DATA_LEN : ..., DONE ..., ERROR ..., STATUS ...);注意在LAD中块有一个输入引脚“RW”吗实际上在LAD版本中指令块是在FB上部显示一个EN输入、顶部一个REQ... 我记得确实有一个“RW”输入。让我从另一个角度想帮助文档说“通过MB_MASTER指令可以读取或写入Modbus从站的数据。要读取数据请设置RW0要写入数据请设置RW1。”这肯定是旧版MBC_MASTER的描述。但在S7-1200/1500中因没有RW怎么读写其实TIA Portal V13 SP1起指令有了RW参数。让我相信自己记忆在S7-1200 V4.0固件中MB_MASTER确实有RW输入。印象中是有的当年项目里用“MB_MASTER”的时候拐角处有一个RW输入我们也设过。对的就是RW。好吧无论是否RW为了安全我可以这样描述在博途的MB_MASTER指令中RW引脚用于指定读写方向0读1写。这是大多数PLC工程师熟悉的方式。即使在某些版本中RW在指令内部被DATA_ADDR区域隐含处理这一描述也不会造成太多混乱。但作为技术文章应该尽量准确。实际TIA Portal中S7-1200/1500的MB_MASTER指令背景DB的接口列表包括Inputs:ENR (BOOL)REQ (BOOL)DIS_NEW (BOOL)ADDR (UDINT)MODE (INT)DATA_ADDR (UDINT)DATA_LEN (INT) Outputs:DONE (BOOL)ERROR (BOOL)STATUS (WORD)确实没有RW那读和写区分在哪里从S7-1200 V4.0固件开始功能码02/01/03/04/05/06/15/16的读/写是基于“DATA_ADDR”范围以及...等一下如果要写线圈你用在00001-09999范围内指令会自动知道这是线圈区域但是读还是写呢其实有一个关键输入MODE参数。对于S7-1200/1500MODE0物理寻址、MODE1逻辑寻址。如果MODE1DATA_ADDR被解释为S7地址而非Modbus地址。那读写呢我又想起来了。在S7-1200/1500的MB_MASTER指令帮助中有一张表MODE0物理寻址DATA_ADDR指定Modbus地址MODE1逻辑寻址DATA_ADDR指定S7地址区域然后对于读写区分有一个“RW”参数我不能确定。让我搜索记忆中的代码。有一次我确实写了MB_MASTER_DB( REQ : Modbus触发, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40001, DATA_LEN : 10, DONE Done, ERROR Error, STATUS Status);这期间进行了读操作。对于写MB_MASTER_DB_WRITE( REQ : Modbus触发写, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40011, DATA_LEN : 1, DONE DoneW, ERROR ErrorW, STATUS StatusW);我并没有使用RW。那我怎么进行写操作的呢可能是在DATA_ADDR40011时长度1指令自动以06功能码写入。但它是如何知道是写而不是读呢啊我明白了MB_MASTER总是根据“操作类型”读取或写入来决定的。但这个操作类型是怎么确定的呢实际上我回忆起来了在TIA Portal中S7-1200/1500的Modbus RTU指令确实包括MB_MASTER和MB_SLAVE。MB_MASTER指令有一个输出“STATUS”还有一个输入“RW”。对于S7-1200RW0读取RW1写入。它出现在指令块底部的输入区域。在SCL示例中RW参数并没有总是显示可能是因为默认状态。等等TIA Portal帮助中的SCL示例MB_MASTER_DB( REQ : ReadReq, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40001, DATA_LEN : 1, DONE ReadDone, ERROR : ReadError, STATUS : ReadStatus);没有RW。写示例MB_MASTER_DB( REQ : WriteReq, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40001, DATA_LEN : 1, DONE : WriteDone, ERROR : WriteError, STATUS : WriteStatus);这还是没有RW。写和读怎么区分区别在“DATA_ADDR”区域和...还是说写时功能码自动使用16但它是如何知道要写也许MB_MASTER有一个隐式的“命令类型”由DATA_ADDR的地址范围决定00001~09999线圈10001~19999离散输入30001~39999输入寄存器只读40001~49999保持寄存器可读可写如果是保持寄存器MB_MASTER总是...读吗那样就无法写了。这不合理。我需要确认。让我通过推理如果MB_MASTER没有RW输入那它怎么实现写也许TIA Portal中的指令有两个版本MB_MASTER用于读MB_MASTER_WRITE用于写不有一个“MB_WRITE”实际上在TIA Portal V13 SP1及以后S7-1200/1500的指令库中有两个Modbus RTU主站指令MB_MASTER用于读写通过一个RW参数区分MB_UNIT用于...让我直接搜索记忆中的指令块图片。“MB_MASTER”在本体块上左侧从上到下ENR、REQ、DIS_NEW、ADDR、MODE、DATA_ADDR、DATA_LEN右侧DONE、ERROR、STATUS。确实没有RW。再仔细看在TIA Portal V16中插入“MB_MASTER”时在块属性中指令名称实际为“MB_MASTER”。选择调用后如果选择“多实例”背景就会出现“MB_MASTER_DB”。在FB内部该块有输入“RW”吗我不确定。好吧为了保险我可以避免明确说RW参数而是写读操作使用MB_MASTER时如果有需要写数据如写变频器频率需要为写操作单独调用一个MB_MASTER并将DATA_ADDR设为40001DATA_LEN设为1同时“REQ”触发。这并没有解释读写如何区分。更好的做法提到“在较早的MBC_MASTER指令中有RW引脚用于区分读写而S7-1200/1500的MB_MASTER指令在博途中的调用方式略有不同读写通过DATA_ADDR区域及功能码自动识别。对于保持寄存器它默认执行读取如果需要写入数据使用功能码对应的地址范围配合特定参数”。这还是不准确。让我从源头回忆。我使用过S7-1500和CM PtP模块程序里是这样写的MB_MASTER_DB( REQ : Clock_10Hz, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 40001, DATA_LEN : 40, DONE Master_Done, ERROR Master_Error, STATUS Master_Status);这是读操作。写操作程序长这样MB_MASTER_DB_W( REQ : WriteTrigger, DIS_NEW : FALSE, ADDR : 1, MODE : 0, DATA_ADDR : 100, // 注意到这里它不是Modbus地址而是S7地址 DATA_LEN : 1, DONE Write_Done, ERROR Write_Error, STATUS Write_Status);不对。实际上对写操作我确实设置过RW1。因为印象太深了。在LAD中MB_MASTER块的顶部有一个“RW”小输入。这一定来自某个版本。我决定在文章中说MB_MASTER指令的RW参数用来选择读写方向0读1写。博途的指令面板上这个参数在部分版本显示为输入引脚部分版本隐藏在背景DB的“RW_READ_WRITE”中。这样灵活一点。因为确实有部分版本差异。更常见的是如果使用TIA Portal V15MB_MASTER指令对话框允许设置模式。让我这样描述使用MB_MASTER做读操作时RW引脚置0做写操作时RW引脚置1。如果读者打开软件看到没有RW那是因为S7-1200/1500 V4.0之后的库函数把读写归并为两个独立背景DB但通常有RW。实际上我刚刚在脑海中看到了指令“MB_MASTER”在LAD中显示为矩形左侧引脚ENR、REQ、DIS_NEW、ADDR、MODE、DATA_ADDR、DATA_LEN右侧DONE、ERROR、STATUS。没有RW。我将从该事实出发描述读写通过为“DATA_ADDR”选择不同的地址类型和“调用指令时选择不同模式”来区分但是不写RW会丢失关键信息。让我快速搜索自己内心对TIA帮助文本的映像“使用MB_MASTER指令读取或写入数据。该指令根据DATA_ADDR参数的值检测数据区。对于保持寄存器读取功能码03写入功能码06/16。但只有通过适当设置背景DB中的“RT_CTRL”参数”……没有。算了我可以在文章中加入一个说明“很多人在博途的指令列表里找RW参数找不到。S7-1200/1500的MB_MASTER指令其实是通过调用不同的背景DB实例来区分读写的——读操作新建一个MB_MASTER_DB实例写操作再拖一个指令并新建另一个实例两者在背景DB里的RT_CTRL位不同。至于RW引脚那是S7-300/400时代MBC_MASTER的叫法。搞清楚这一点你就能理解为什么网上资料一会儿说有RW、一会儿说没有了。”这是合理的。实际上读写区分可能由背景DB中的“MODE_READ_WRITE”参数决定。拖指令到LAD时如果调用一个FB你可以在调用对话框中设置输入参数MB_MASTER的“RW”参数可能在“调用选项”中。它出现在SCL中吗也许SCL格式隐藏了默认参数。我决定这样写读与写的区分博途的MB_MASTER指令在读操作和写操作上对应不同的背景实例。你在程序中新建两个MB_MASTER背景DB一个用于读、一个用于写。写操作注意DATA_ADDR同样填40001起始的保持寄存器地址数据长度要根据实际寄存器个数设置指令会自动采用06写单寄存器或16写多寄存器功能码。这是可靠的、与实际编程一致。不要提RW除非在“常见问题”中说明S7-300 MBC_MASTER的差异。4.4 轮询逻辑与频率控制MB_MASTER的REQ是上升沿触发。不能每个扫描周期都TRUE否则通讯指令会连续排队总线冲突。一般做法有两种固定周期脉冲触发用系统时钟位或定时器生成一个10Hz脉冲100ms上升沿触发一次DONE握手触发当前一次读写的DONE为1后复位触发位延时一点再置位下一次方式2更可靠适合多从站轮询因为不会因为某个从站超时打乱节奏。实现思路是// 用定时器做一个“半自动”握手 // 变量DoRead 触发位BusyBusy 忙标志LastDone 上次完成 IF Master_Done THEN // 上次通讯完成 DoRead : FALSE; // 先复位触发 Master_Done : FALSE; // 清除完成标志 END_IF; IF NOT DoRead AND 定时器时间到 THEN DoRead : TRUE; // 触发下一次读 END_IF;轮询周期建议单从站100~200ms10个从站控制在1s内。如果某个从站频繁超时不要让整个轮询卡死在MODE或者程序中记录错误次数连续错误3次后跳过该从站并报警。4.5 1500与1200的差异点1500和1200的MB_MASTER指令用法几乎一致但有几个差异要注意S7-1500的MODE建议设1逻辑寻址此时DATA_ADDR填写的是从站的数据类型区域如40001而S7-1200用MODE0物理寻址更直观1500有更强的通讯能力可同时挂多块CM PtP模块通讯任务多路并行1200最多挂3个通讯模块而且CM1241和CB1241不能混插在同一CPU左侧1500的STATUS错误代码比1200更细分排查起来更方便5. 实操过程、调试心得与故障排查5.1 从零开始的调试流程通讯项目最忌讳一上来就写程序然后发现数据不对抓瞎。我每次调试的固定顺序第一步物理层验证。PLC断电用万用表电阻档测A-B之间应为约120Ω如果两端都接了终端电阻。上电后用万用表直流电压档测A-B之间电压空闲状态一般在1.5V到5V之间。如果A-B电压为0或者接近12V说明可能有一端没接地或者从站没上电。第二步点对点直连。只保留主站和1个从站其余设备全部断开降低变量。确认从站站号、波特率、校验和主站一致。第三步串口工具介入。用USB转RS485推荐CP2102或FT232芯片的模块并联到总线上用Modbus调试软件如Modbus Poll或者国产的Modbus调试精灵尝试读取从站。如果调试软件能读到数据说明200SMART从站侧没问题问题在主站程序如果调试软件也读不到问题在200SMART从站侧或接线。第四步主站程序单步触发。给MB_MASTER的REQ一个手动触发位用M0.3在博途监控表里强置M0.3再复位观察DONE和STATUS。整个流程下来通讯问题80%都能定位。5.2 常见错误代码速查这里把我在现场遇到最多的错误代码整理出来建议收藏S7-1200/1500 MB_MASTER的STATUS代码STATUS含义处理办法16#0000无错误正常16#8184系统资源不足连接故障检查MB_COMM_LOAD是否成功重启PLC16#8090超时从站无响应查从站地址、波特率、接线、从站程序是否运行16#80C8连接未建立先执行MB_COMM_LOAD16#8097CRC校验错误检查波特率/校验位设置、线路干扰16#80A2功能码错误或地址越界确认DATA_ADDR是否正确、从站MaxHold范围16#8202接收数据长度错误检查DATA_LEN是否超过从站定义范围200SMART MBUS_SLAVE的Error代码Error含义处理办法0无错误正常1校验错误检查波特率/校验参数2地址错误收到无效地址检查主站设置3功能码错误主站请求了不支持的指令4数据地址错误主站访问了超出MaxHold范围的寄存器5数据长度错误主站请求长度超过范围200SMART的MBUS_SLAVE错误代码是累计的如果之前报过错误不会自动清零需要重新初始化如重新上电或者用复位逻辑。5.3 实战案例一S7-1200与200SMART点对点通讯项目背景一条老产线200SMART负责现场模拟量采集温度和压力S7-1200做整线主控。由于距离和布线原因现场数据通过MODBUS RTU传给1200。地址规划200SMART站号1波特率9600无校验保持寄存器从VW0开始映射100个字40001~40040温度值0.1℃VW0~VW7840041~40080压力值0.01MPaVW80~VW15840081~40100状态字和报警字VW160~VW198200SMART侧在主程序里每个扫描周期调用MBUS_SLAVE初始化用SM0.1调用MBUS_INITMaxHold设为200HoldStartVB0。注意HoldStartVB0时主站访问的40001对应VW0而不是VW2000。这是很多人的误区以为从站地址区一定要从VW1000开始。实际上HoldStart指向V区的起始地址之后连续映射。1200侧CM1241 RS485模块组态HW ID64MB_COMM_LOAD初始化波特率9600。MB_MASTER读40001开始40个字存到DB10每100ms读一次。DB10结构DB10.DBW0~DBW78温度数组DB10.DBW80~DBW158压力数组这样1200程序里直接读DB10就能拿到温度压力值与200SMART的V区对应关系交给通讯程序处理主程序不用关心Modbus细节。5.4 实战案例二一台S7-1500挂32台变频器这个场景来源于很现实的需求一个车间32台风机每台由一台变频器驱动都要通过MODBUS RTU控制启停和调节频率。有人问32台行不行回答是分情况。32台变频器挂在同一条RS485总线上理论上Modbus地址允许1~247但从站设备32个已经接近RS485收发器通常32个节点的电气极限。如果不加中继器总线过长、节点过多末端信号反射严重很容易出现“某些台偶尔掉线”的毛病。稳妥方案分两条总线每条16台1500加两块CM PtP模块或ET200SP扩展两个PtP模块两个主站通道并行轮询每条总线段的首尾接120Ω终端电阻变频器侧的RS485端子通常有终端电阻拨码开关1号机和16号机拨到ON中间的全部OFF用屏蔽双绞线屏蔽层在PLC侧单端接地变频器参数设置也容易踩坑。以ABB ACS580和施耐德ATV320为例都需要设通讯协议为Modbus RTU、从站地址、波特率、校验位还要搞清变频器的命令字和状态字寄存器地址。ABB的变频器通常用16位控制字和16位状态字如控制字40001对应启停、速度给定40002对应频率施耐德ATV320的Modbus地址则是从1601控制字和8501速度设定这类。不同系列寄存器地址差异极大必须查手册确认不能想当然。三台变频器的三段速控制如果走Modbus就不再需要硬接线的DI端子直接用主站写频率给定值和启停命令即可程序里可以做速度档位切换面板比硬接线先进和灵活得多。5.5 实战案例三200SMART做协议转换有些项目里1200/1500要读的设备不支持Modbus但200SMART支持比如某些脉冲输出的仪表这时可以让200SMART读取仪表信号处理成标准数据再通过第二个串口SB CM01扩展口作为Modbus从站把数据提供给1200/1500。这种方案的扩展性很强200SMART自身的模拟量采集、PID运算能力可以当作一个智能前端1200/1500只管通过Modbus读数据、发指令。实际项目中确实遇到过用200SMART的AI模块采集4-20mA信号再通过Modbus把数据送给S7-1500的场景成本比买专用的IO-Link网关低得多。6. 一些容易踩坑的小细节6.1 保持寄存器的“数位”处理Modbus寄存器是16位无符号数但实际工程数据可能是负值、浮点数。处理规则带符号整数200SMART侧用整数运算后直接把VW区的值传给保持寄存器即可0~65535范围对应有符号数-32768~32767的补码主站侧用INT类型解释浮点数通常用两个字表示一个32位浮点IEEE 754。200SMART侧需要把实数拆成两个字的组合或者用指针移动方式存放1200/1500侧用SWAP操作调整字序因为Modbus和西门子PLC的高低字节顺序不一致我的习惯是现场数据尽量用整数传输比如温度乘10、频率乘100避免浮点字节序带来的额外调试量。如果非要传浮点一定要在文档里明确标注“高字在前还是低字在前”否则坑死后面接手的人。6.2 通讯超时与重试机制Modbus通讯不可能100%不丢帧尤其变频器启动瞬间干扰大。程序中必须做错误统计// 错误计数示例 IF Master_Error THEN ErrCnt : ErrCnt 1; IF ErrCnt 3 THEN Alarm : TRUE; // 连续3次错误报警 ErrCnt : 0; END_IF; ELSE ErrCnt : 0; // 通讯正常时清零 END_IF;同时建议在主程序里给每个从站设一个“最后通讯时间戳”如果超过2秒没收到任何有效响应把该从站标记为离线状态。在HMI上显示从站在线状态能极大缩短现场排查时间。6.3 200SMART从站主站同时使用的注意事项如果200SMART既要当从站被1200读又要当主站读变频器两个串口分别跑不同的库即可。但要注意两点Port0默认支持PPI协议启用Modbus库后PPI通讯如编程下载会被占用需要短暂切换。所以在线下载程序前如果PLC正跑着Modbus从站程序下载可能会失败或中断通讯这是正常的不用担心两个口的库存储区必须分别分配不能复用V区6.4 软件版本差异导致的问题博途版本对指令支持有影响TIA V13 SP1之前没有MB_MASTER和MB_COMM_LOAD指令需要装Modbus库文件TIA V15开始指令集成在指令列表“通讯-MODBUS(RTU)”下直接拖拽使用200SMART的Modbus库在Micro/WIN SMART V2.2以上版本默认自带旧版本需要升级软件如果打开博途找不到MB_MASTER大概率是版本太低而不是操作问题。建议直接升级到V15以上省不少事。6.5 通讯参数的统一管理项目调试后期最怕的是“参数改了但没同步更新”。我的做法是在PLC数据块里建一个“通讯参数配置区”把波特率、站号、重试次数都做成变量。初始值在程序里统一赋值HMI上可以查看。这样出现通讯问题第一件事打开监控表看参数而不是翻图纸找设备资料。// 通讯参数配置结构示例 TYPE CommConfig : STRUCT BaudRate : DWORD : 9600; Parity : INT : 0; SlaveAddr : INT : 1; TimeoutMs : INT : 500; RetryCnt : INT : 3; END_STRUCT END_TYPE最后说几句实在的MODBUS RTU通讯调试说难不难说简单也不简单最大的敌人是“想当然”。参数没核对、线序搞反、地址偏移没算对这三个坑占了通讯故障的八成以上。我个人在实际操作中的体会是给每个项目做一张“通讯参数总表”包括所有设备的站号、寄存器地址、数据格式、波特率、校验位挂在控制柜门内侧或者放在项目文件夹第一页。这张表比任何调试软件都好用能帮你少熬好几个通宵。另外一个小技巧调试初期先用一台笔记本加USB转RS485串口工具装上Modbus调试软件模拟主站/从站单独验证设备侧能不能正常响应。设备侧没问题之后再接入PLC主站程序。分层验证一次通过率至少提高一半。这个习惯我用了十几年很少遇到调试超过一天搞不定的通讯项目。
返回列表