资讯详情

资讯详情

PLC梯形图与ST语言混编实战:三种主流写法与选型建议

1. 为什么混编而不是二选一梯形图和ST各自的边界1.1 梯形图的舒适区其实很窄梯形图是PLC最古老也最普及的编程语言本质是继电器控制回路的图形化表达。接触器、继电器怎么接梯形图就怎么画左母线是火线右母线是零线常开常闭触点串联并联最后驱动线圈。老一辈电气工程师看梯形图就像看电气原理图几乎不需要额外培训。这种图形化特性决定了梯形图的优势场景非常集中正反转互锁、星三角启动、安全门联锁、急停回路、气缸到位检测、电机启停控制这类“触点逻辑密集”的程序梯形图是当之无愧的第一选择。一个完整的电机正反转回路梯形图十几行就画完了而且现场电工肉眼就能排查哪里有故障。但梯形图的短板也同样明显。只要逻辑里出现“循环”“数组”“批量计算”“复杂公式”梯形图就开始露出丑态。我印象最深的是几年前做一台老设备改造客户要求在触摸屏上统计当日产量、良品率、设备OEE还要按班次存到数组里方便查询。用梯形图写这套数据统计我写了将近三百行全是MOV、ADD、CMP、INC的堆叠光数组下标的管理就用了七八个变址寄存器改一个统计口径要翻半天程序在线查找触点。那个过程非常痛苦调完以后我自己都不太想去维护它。1.2 ST语言的两面性ST语言结构化文本是IEC 61131-3标准里最接近高级编程语言的一种PLC语言。它的语法类似Pascal或者C语言支持变量声明、IF/ELSE分支、FOR/WHILE循环、CASE状态机、数组和结构体。凡是你觉得梯形图写起来别扭的逻辑换到ST里往往几行就搞定。举一个非常普遍的例子S7-1200里把十进制转十六进制的拆分、字节拼接、字符串拼装这类数据处理程序用梯形图写要一个字节一个字节地拆出来然后用MOV指令拼到目标寄存器里既啰嗦又容易错。用SCL西门子对ST的实现写就是两三句赋值语句的事。这也是为什么很多西门子工程师在做配方管理、数据块搬运、通信协议解析时都会转向SCL。但ST有个致命问题它不直观。梯形图里一个触点从上到下扫一眼就知道回路通不通而ST的IF条件嵌在三行代码里要靠在线监视才能确认当前走了哪个分支。纯ST项目交付以后客户电气维修人员往往不敢下手。我之前接过一个外包维护的项目前一家公司全套程序用ST写的设备一出报警业主的电工只能干瞪眼必须打电话找原开发公司远程处理。这绝对不是代码水平的问题而是ST这种文本形式天然就不适合现场快速排查。1.3 混编的本质是接口管理“混编”这两个字容易让人误解以为是把ST代码和梯形图画在同一个屏幕里实际上不是这样。IEC 61131-3标准本身支持多种语言共存工程里既可以有梯形图程序块也可以有ST程序块它们之间的协作靠的是“程序组织单元POU”和“变量接口”。换句话说混编的核心不是语言本身而是接口管理。一个ST功能块对外暴露哪些输入变量、哪些输出变量内部逻辑怎么实现梯形图侧完全不需要关心反过来ST主控程序调用一个梯形图子程序时只需要给它需要的状态和使能信号梯形图内部怎么联锁也不关ST的事。基于这个思路我在实际项目里总结出了三种主流混编写法分别适用于不同的控制系统架构和团队配置后面一个个展开讲。2. 写法一梯形图作主程序ST功能块作算法黑盒2.1 适用场景和整体思路这是最稳妥、最容易向客户解释的混编方式适合设备逻辑以联锁控制为主、算法数据量为辅的项目。整体结构是梯形图写主程序负责设备启停、互锁、报警、手动自动切换所有需要计算的东西——数据滤波、平均值、数组排序、流量累积、校验码计算——全部封装成ST功能块在梯形图里通过一个“功能块调用”指令即可使用。这种写法的最大好处是维护边界清晰懂梯形图的人看主程序就能明白设备动作流程ST功能块像一颗颗螺丝钉插在梯形图框架上。功能块内部写错了只需要打开对应的ST功能块修改不影响其他页面。2.2 以Codesys生态为例的完整实操步骤我平时用得最多的平台是Codesys以及基于Codesys二次开发的国产PLC比如信捷XD系列、汇川H系列操作逻辑基本一致。下面以一个“十通道温度采集求平均值并找最大值”的功能块为例把步骤完整走一遍。第一步建立ST功能块。在工程树里右键选择“添加对象→功能块”语言类型选ST。然后定义接口变量FUNCTION_BLOCK FB_ArrayCalc VAR_INPUT bEnable : BOOL; // 允许计算 arrRawData : ARRAY[0..9] OF REAL; // 十通道原始数据 END_VAR VAR_OUTPUT rAverage : REAL; // 平均值 rMaxValue : REAL; // 最大值 bValid : BOOL; // 数据有效标志 END_VAR VAR i : INT; // 循环计数 END_VAR第二步写内部逻辑。这里用循环实现累加和最大值判断梯形图最头疼的部分在这几行里解决IF bEnable THEN rAverage : 0; rMaxValue : arrRawData[0]; bValid : TRUE; FOR i : 0 TO 9 DO rAverage : rAverage arrRawData[i]; IF arrRawData[i] rMaxValue THEN rMaxValue : arrRawData[i]; END_IF; END_FOR; rAverage : rAverage / 10; ELSE bValid : FALSE; END_IF;第三步编译这个功能块然后回到梯形图页面。在指令树的“功能块调用”类目下找到FB_ArrayCalc拖进梯形图网络里。此时IDE会自动生成一个功能块调用线圈顶部是输入引脚底部是输出引脚。你需要做的是bEnable接一个控制字BOOL变量比如“计算使能”arrRawData接数据块里的温度数组变量rAverage接到一个REAL变量用于触摸屏显示rMaxValue接到最大值显示变量bValid接到一个内部BOOL可以参与报警判断。第四步注意数据类型匹配。数组变量必须和功能块声明的类型完全一致差一点都不通。很多新手在这里卡住比如梯形图里的数据是从模拟量通道采集的INT型而功能块声明的是REAL数组就需要在数据块里先做一次类型转换再接入。2.3 这个写法里最容易踩的坑功能块没有“门控”导致每个扫描周期都执行。这个问题很隐蔽。如果梯形图侧没有给bEnable加前置条件而是让bEnable常量置TRUE那功能块每周期都会循环十次。在Codesys里这不算问题但在一些老式PLC上会影响扫描周期甚至触发看门狗。我在信捷XD系列上就遇到过类似情况解决方式是bEnable只在数据刷新完成沿之后置TRUE计算完立即复位既保证了数据新鲜度又减少不必要的CPU开销。数组越界是另一个高频事故。ST功能块内部如果引用了arrRawData下标为10的元素在线运行时不会像PC程序那样直接报错而是可能读到前后变量。这个错误极其隐蔽因为功能块输出看起来还正常但数据已经错了。排查方法很简单FOR循环的下标范围必须和数组声明一致任何常量下标都建议写成数组的上限值不要写死数字。在线监控也要提前规划。梯形图页面只能看到功能块的输入输出引脚看不到内部变量。如果你希望在调试时监视功能块内部的i循环计数或者中间变量最好在ST功能块的接口区额外加几个“监视变量”或者在IO映射里建立测试点。等程序下载运行后再想加变量就得停机重新编译下载成本很高。3. 写法二ST做状态机大脑梯形图做设备四肢3.1 哪些设备最适合“ST主控梯形图执行”如果你面对的是一台多工位自动化设备自动运行流程有十几个甚至几十个状态每种状态都要协调一堆伺服、气缸、夹紧机构那么梯形图硬写状态机就是一场噩梦。举个例子一台三轴搬运设备自动流程包括回零、等待取料、取料确认、移送、放料确认、复位每个工位还有独立的伺服动作和气缸联锁。如果用梯形图写状态跳转每一行都要判断“当前状态完成条件下一状态”几十个状态的跳转矩阵轻松超过五百行检查和修改都是一场灾难。但如果你把一个工位的气缸联锁逻辑用ST写又会陷入前面说的可维护性困局。所以这个场景下最佳方案是ST写状态机主控梯形图写硬件联锁回路。我把这种架构叫作“大脑和四肢分离”——ST是大脑负责判断状态、下发指令、收集反馈梯形图是四肢负责把设备动作和硬件安全回路落到实处。3.2 具体实现CASE语句驱动梯形图子程序在这种写法里ST主控程序通常用CASE语句组织状态跳转CASE byStep OF 0: // 回零状态 fbHomeREQ(bEnable : TRUE); IF bHomeDone THEN byStep : 1; END_IF; 1: // 等待取料 fbWaitReady(bEnable : TRUE); IF bPickReady THEN byStep : 2; END_IF; 2: // 取料执行 fbPickInProgress(bEnable : TRUE); IF bPickDone THEN byStep : 3; END_IF; END_CASE;这里的关键是把每个状态对应的设备动作封装成一个个动作功能块动作功能块内部再调用梯形图子程序。或者更简单一点在ST主控里把当前状态对应的“允许动作标志位”置TRUE梯形图页面的每一个网络都依赖这些标志位来输出。梯形图那一侧写什么写最纯粹的逻辑伺服使能必须同时满足伺服报警未触发且急停释放且状态机的取料允许标志为TRUE气缸伸出必须同时满足夹具到位且没有工件触碰报警。这些逻辑放在梯形图里电气工程师现场拿万用表都能顺着线路查而不用去理解ST里的CASE跳转逻辑。3.3 实例展开三轴搬运设备的自动运行状态状态机和梯形图的协作细节我拿一个具体的取料工位来说。ST主控在“取料”状态下发bPickAllow为TRUE此时梯形图侧的取料输出网络才允许动作安全门关闭、急停未触发、伺服就绪、取料允许标志为TRUE这四个条件串联在一起只有在全部满足时输出Q0.0才给伺服使能线圈通电。再往下伺服使能信号加上夹具夹紧到位反馈才输出气缸动作。这套结构的调试体验我很喜欢。手动模式可以完全绕过ST状态机——手动按钮直接驱动梯形图输出不需要状态机介入。自动模式时则是ST先动作把允许标志翻转后再等待梯形图的执行结果。只要把手动输出和自动输出做了互锁现场的“手自动切换”就会无比顺畅因为梯形图负责的是最底层的输出线圈ST永远不直接驱动物理输出。3.4 这种写法的三个关键要点第一状态号一定要定义成符号常量不要直接用裸数字。我习惯在最前面把状态枚举写清楚VAR CONSTANT STATE_HOME : INT : 0; STATE_WAIT_PICK : INT : 1; STATE_PICK : INT : 2; STATE_MOVE : INT : 3; STATE_PLACE : INT : 4; END_VAR这样CASE里写的就不是跳转数字而是状态名称别人看你代码的时候不需要拿一张状态表来回对照。第二ST侧下发的是“允许”信号不是“动作”信号。同样是驱动一个气缸让ST输出一个“请伸出”的BOOL不如让ST输出一个“允许伸出”的标志然后由梯形图综合判断安全条件后输出。区别很大“请伸出”是命令梯形图必须无条件执行而“允许伸出”是授权梯形图有权因为安全条件不满足而拒绝伸出。这个设计思想保住了安全底线。第三状态跳转的条件尽量使用沿信号。一台多工位设备各工位动作时间不同状态机跳转过快会导致下一工序还没准备好就开始执行。我一般会在梯形图侧把所有到位信号汇总后用一个上升沿触发状态机的“工序完成”标志。这样即使某个传感器短暂闪断也不会造成状态误跳。4. 写法三同一逻辑内部的“内嵌式”混编4.1 什么才算内嵌式混编前两种写法本质上都是“块级混编”——一个块是ST另一个块是梯形图靠调用关系协作。但有些PLC平台还支持在同一个逻辑单元内部把ST语句直接嵌到梯形图网络里。这种写法的变化多、平台差异大所以单独拿出来讲。最典型的实现是三菱GX Works3。在结构化梯形图工程里你可以把一个梯形图网络的输出部分替代为一个“ST语句盒”梯形图的触点条件控制这个ST语句盒是否执行。这样既保留了梯形图的条件判断又在同一行里完成了复杂表达式。另一个常见场景是Codesys生态下的SFC顺序功能图编程SFC的“转换条件”可以选择ST语言实现。一个转换条件的判断逻辑如果是“取料完成 AND 无报警 AND 定位偏差小于0.5”用梯形图要画三个比较器再加AND串联但用ST表达式一行就写完了。4.2 两个真实场景的展开先看GX Works3里的ST语句盒。假设我有一个拨码开关读取的十六进制数据存在D200里想在设备启动时把它转换成十进制数值并判断是否在正常范围内。梯形图网络前面是启动条件触点触点后面插入一个ST语句盒盒内写D100 : BCD_TO_INT(D200); IF D100 0 THEN M20 : TRUE; END_IF;梯形图的触点条件满足时这个语句盒才会执行不满足时D100保持原值M20不动作。这种写法把一个百来行的、由各种CMP、BCD、MOV指令组合起来的网络压缩成了两行可读性极高的ST语句。调试效率提升非常明显。再看Codesys SFC的转换条件。你在SFC图表里拖动一个转换元素双击打开编辑器语言选ST然后输入bPickDone AND NOT bAlarm AND ABS(rActualPos - rTargetPos) 0.5这个表达式的计算结果就是转换条件。如果用梯形图实现同样的判断得插入三个比较指令再串起来尤其在变量名很长的时候梯形图连线会非常拥挤图形错位一调整就是半小时。4.3 内嵌式写法的限制和注意事项在线监控能力弱是内嵌式写法最大的短板。普通梯形图网络在线监视时每个触点和线圈都有绿/灰色状态显示而ST语句盒只能看到整体执行结果变量语句盒内部每一行的条件分支并不能像ST程序块那样逐行高亮。如果语句盒里写了一个复杂的IF嵌套中途出错时不太好定位。另一个要注意的风险是执行级别。梯形图触点控制的ST语句盒本质上是每个扫描周期执行一次它内部如果写了很大的循环体会直接影响扫描周期。我之前见过一位同事在内嵌ST盒里写了一个FOR 0 TO 10000的空循环用于延时结果PLC扫描周期直接爆表CPU直接亮红灯。这种用途应该用延时定时器而不是循环硬跑。还有一个务实建议内嵌ST语句盒里的代码尽量不依赖PLC具体品牌指令。BCD_TO_INT这种指令换一个平台就不存在了移植性极差。我一般只在内嵌位置写ADD、SUB、IF、CASE这种标准语句特殊指令还是放到功能块里封装。4.4 各平台混编支持程度的真实差异这部分信息很重要因为很多工程师拿着一个平台的习惯去另一个平台找功能结果一脚踩空。平台/软件混编支持方式主要限制西门子TIA PortalS7-1200/1500块级混编梯形图OB调用SCL编写的FC/FB反之亦可同一块内不支持混写不能在一个梯形图网络里嵌入SCL文本SCL中调用梯形图块也需要先定义实例Codesys及国产Codesys类汇川、信捷部分型号等块级混编为主SFC动作/转换条件可选择不同语言普通LD梯形图内不提供ST语句盒但SFC内混编很灵活三菱GX Works3FX5U及以上支持梯形图网络内插入ST语句盒ST语句盒内不能调用梯形图块代码过长时监控困难传统三菱FX3UGX Works2基本不支持真正的ST混编FX3U需用结构化梯形图变址间接实现复杂数据处理仍然别扭信捷XD系列XDPPro支持ST功能块与梯形图互相调用块级混编成熟内嵌式表达支持程度取决于具体版本建议先做编译验证5. 三种写法怎么选选型建议与实际体会5.1 关键差异一览表三种写法不是替代关系而是适用于不同项目阶段和控制架构。我用一张表把核心差异列出来方便你按自己手里的项目去套对比维度写法一梯形图壳ST芯写法二ST大脑梯形图四肢写法三内嵌式混编程序组织梯形图为主ST功能块按需插入ST作为主控层调用梯形图子程序同一网络内梯形图触点ST语句可维护性很好边界清晰较好但要求维护人员理解状态机概念一般在线监控能力弱调试难度较低ST块内部可用监视变量观察中等状态跳转要靠变量表辅助较高语句盒内分支不如梯形图直观适合场景传统设备控制算法辅助多工位自动化、流程复杂设备协议解析、条件判断密集的小型逻辑对团队要求电工能看梯形图编程人员熟悉ST需要一个能写ST状态机的工程师调试工具熟练熟悉平台特别功能5.2 我的固定套路踩了不少坑之后我现在接手新项目基本会按下面这套惯例划分语言凡是和安全、急停、互锁、门禁相关的逻辑一律梯形图没得商量。这类逻辑出问题的代价是安全事故和人身伤害必须让设备现场任何一个电气人员都能直观检查。凡是批量计算、数据处理、协议解析、复杂数学运算一律ST功能块。这些逻辑不追求可视化只追求代码简洁和修改方便。二十个浮点数求平均值梯形图要写一屏ST只要一个FOR循环。凡是多工位、自动流程、状态机类型的逻辑用ST主控但只下发给梯形图“允许”信号绝不直接输出到物理点。这样状态流程的修改不会影响安全回路安全回路的变更也不会导致状态机逻辑崩溃。凡是伺服、气缸、变频器的底层驱动和反馈处理放在梯形图里。这些点位多、接线杂、回路逻辑相似梯形图的触点和线圈形式最方便排查IO信号。5.3 混编项目的工程化管理建议语言混编之后程序的可读性瓶颈往往不在代码本身而在接口变量命名混乱。我见过太多项目里ST功能块的输入输出叫A1、B2、TEMP这种名字梯形图侧根本分不清谁是谁。现在我强制自己用一套简单前缀来自梯形图的输入变量名以LD_开头来自ST的变量名以ST_开头跨层传递的全局标志统一放数据块并写注释说明来源和去向。接口文档也建议提前做。我在项目启动阶段会维护一张Excel表格每个ST功能块一行列清楚功能块名称、输入变量、类型、来源块、输出变量、去向块、备注说明。这张表在前期设计时看起来像多余工作到了调试后期联调阶段你会发现它的价值——不用翻十几个文件就能知道某个BOOL变量是从哪来的是谁置位的。最后提醒一个在线改动的问题。梯形图支持在线修改部分页面并下载但在ST功能块内部修改了逻辑之后绝大多数PLC都需要整体编译并下载整个程序块。如果你在自动运行状态下改了一个ST块的参数一定要确认当前设备处于安全位置否则下载瞬间的输出状态跳变可能会让设备来个意外动作。我在现场有一次深夜加班改配方程序就是在自动状态下下载了ST块结果气缸瞬间动作幸好对着空料位不然后果不敢想。三种写法我实际都用过没有一种能包打天下。真正好用的混编方案是在项目需求阶段就想清楚每一段逻辑该用什么语言。语言只是工具设备稳定运行、维护人员能接手才是最后要交的答卷。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →