1. 从一门老手艺讲起:为什么PLC编程需要国际标准
干了好几年PLC项目的工程师,没人不知道IEC 61131-3。这个标准说白了就是给PLC编程语言定的一套“普通话”,让西门子、三菱、罗克韦尔、施耐德、汇川、台达这些品牌虽然各说各的方言,但底层逻辑能互通。我刚入行那会儿,从三菱FX系列跳到西门子S7-1200,最大的感受不是硬件差异,而是编程思路的转换成本太高——三菱的梯形图习惯和西门子的函数块思维完全是两套体系。后来真正看懂IEC 61131-3,才明白这标准解决的就是“工程师换品牌要重新学”这个大痛点。
很多人以为五种语言就是五种工具,随便挑一个用就行。真到项目上你会发现,这五种语言各有各的脾气,有的适合画逻辑,有的适合写算法,有的天生就是用来描述流程的。选错语言不是不能跑,而是后期维护、排查故障的时候能让你多熬几个通宵。本文就围绕IEC 61131-3规定的五种编程语言——梯形图(LD)、功能块图(FBD)、顺序功能图(SFC)、结构化文本(ST)、指令表(IL),把它们的原理、适用场景、实操技巧和踩坑经验一次性说清楚。
这篇内容适合谁看?准备入行PLC的电气工程师、正在学编程语言的自动化专业学生、以及做非标设备调试想系统梳理编程方法的从业者。读完你至少能回答三个问题:这五种语言到底在什么场合用?它们之间能不能混着写?选型时到底听厂家的还是听项目的?
2. 五种语言概览:它们分别解决什么问题
IEC 61131-3把PLC编程语言分成图形化语言和文本化语言两大类。图形化的是梯形图(LD)、功能块图(FBD)、顺序功能图(SFC),文本化的是结构化文本(ST)和指令表(IL)。这个分类不是随便分的,图形化语言胜在直观,适合电气背景的工程师;文本化语言胜在灵活,适合有计算机编程思维的人。下面我逐一拆解每种语言的核心定位。
2.1 梯形图(LD):电气图纸的直接延伸
梯形图是所有PLC语言里最接近传统继电器控制电路的一种。它左右两条母线,中间是触点和线圈,老电气工程师看着继电器图纸就能直接上手。它的核心逻辑就是“导通”和“断开”——左母线是电源,条件满足电流流到右母线,线圈得电。这种语言的优点非常明显:直观、易懂、故障排查快。车间老师傅不懂ST代码,但你给他一张梯形图,他能顺着每个触点很快找到问题在哪。
不过梯形图也有它的局限性。处理模拟量运算、PID调节、复杂数学公式时,梯形图写起来非常痛苦。你见过有人用梯形图去算一个三角函数或者解析一串字符串吗?那画面太美我不敢看。所以在实际项目中,梯形图主要用于开关量逻辑控制,比如电机启停、互锁、顺序启动这些典型的PLC应用场景。
实用建议:初学者一定从梯形图入门,它能帮你建立“扫描周期”、“常开常闭”、“自锁互锁”这些最底层的概念。但别沉迷其中,它只是起点。
2.2 功能块图(FBD):像搭积木一样组逻辑
功能块图的核心思想是把逻辑封装成一个一个的块,输入输出用连线表示。每一个功能块就像一个小封装——加法块、比较块、定时器块、PID块,你要做的就是连线。这种语言在过程控制领域用得极多,因为它和仪表控制图(P&ID)的表达习惯非常契合。
FBD的优势在于结构化。一个复杂系统的控制逻辑,用梯形图可能要几十行,用FBD可以把功能分区画清楚,读起来一目了然。尤其是PID回路、模拟量处理、阀门控制这一类的应用,FBD的先天优势非常明显——它天生是把信号流和数据流具象化的语言。不过它的缺点也很实际:画大项目时连线容易乱,而且层的画面大小有限,一旦块多了,工具图的画面管理就很吃力。
实操中我习惯把FBD用在模拟量处理和小型过程控制,配合自定义功能块复用率很高。比如温度采集、压力转换、流量累计这些,封装成一个FB,不同工位直接拖出来用。
2.3 顺序功能图(SFC):天生为流程控制而生
SFC是用步(Step)和转换(Transition)来描述系统运行流程的。你想象一个生产线的流程:上料——>夹紧——>加工——>松开——>下料,每一步有对应的动作,每两个步之间有一个转换条件。这种描述方式天然贴合工艺流程,特别适合周期性重复、带明确状态变化的生产设备。
SFC最强大的地方在于,它把复杂的连锁逻辑拆成了“步”的跳转,跳转条件清楚,当前程序运行到哪一步一眼就能看出来。这在调试多工位设备时简直就是神器——以前排查故障要翻几十页梯形图,用SFC直接看高亮的步就知道在哪卡住了。但SFC也有难度,它要求工程师对设备工艺流程理解非常透彻,而且状态机思维要强。如果流程本身模糊,SFC就会写得一塌糊涂。
给个参考:单机自动化的包装设备、装配设备、输送线控制,SFC是非常优秀的选择。但纯模拟量调节为主的项目,SFC发挥不出优势。
2.4 结构化文本(ST):唯一的“高级语言”
ST的语法和Pascal、C语言非常接近,支持变量声明、IF/ELSE、FOR循环、CASE语句、函数调用。如果五种语言里要选一个“最强大脑”,那一定是ST。它能把复杂的数学运算、数据处理、通信协议解析、算法逻辑写得简洁优雅。比如做视觉定位的坐标变换,或者机械手的轨迹规划插补,用梯形图去写能写到你怀疑人生,用ST几十行代码就搞定了。
ST的价值不仅仅在于写算法,它还能让PLC程序的可读性和维护性大幅提升。程序逻辑再复杂,ST的结构化表达也比满屏触点和线圈好维护。而且现在越来越多的PLC支持ST,甚至有取代IL成为文本语言主流的趋势。你要是懂一点高级语言基础,学ST基本上就是熟悉一下语法的事。
但它也有门槛——如果你完全没接触过代码,ST的变量类型、作用域、函数返回这些概念会让你头疼。我见过不少老电气工程师画梯形图很溜,一碰ST就发怵。这很正常,思维方式不一样。好在现在学习资源多,花一阵子就能上手。
2.5 指令表(IL):老古董,但依然值得了解
指令表是一种类似汇编语言的低层文本语言。它是从早期PLC的指令系统演变来的,格式是“操作符+操作数”,比如LD %I0.1、AND %I0.2、OUT %Q0.0。很多人觉得IL已经是上个时代的东西了,不值得学。这话有道理,但不完全对。在一些老设备维护项目里,你打开程序发现全是IL写的,接不接手、看不看得懂,直接决定你项目的难度。另外,IL是理解PLC工作原理最直接的语言——它没有图形化语言的“包装”,每条指令怎么执行、操作数怎么寻址,一目了然。
我可以负责任地说,IL的实用性在下降,但学习IL对深入理解PLC运行机制非常有帮助。现在IEC 61131-3第三版里IL已经降级为可选语言,很多现代PLC软件默认不支持IL了。所以学IL的心态是“懂原理,不依赖”,真要写复杂逻辑还是用ST。
3. 实操选型:真实项目里怎么组合这五种语言
很多新人会问:“我学哪种语言就够了?”答案是:单用任何一种都不够。实际工程项目里,五种语言经常混着用。这就是IEC 61131-3一个很重要的设计思想——编程模型允许在同一个程序组织单元里使用不同语言。下面我讲讲真实项目中的搭配思路。
3.1 主程序用哪种语言:看项目主旋律
我拿到一个新项目,会先问自己三个问题:主要控制对象是开关量还是模拟量?工艺流程有没有明显的步骤状态?数据处理复杂度高不高?这三问基本能定下主编程语言的方向。
如果是配电柜、MCC控制柜、水泵启停这类以电机控制为主的项目,主程序用梯形图,因为电气维护人员最熟悉这种表达方式,交接方便。如果是温度、压力、流量闭环控制为主,比如加热炉、恒压供水,那主程序用FBD,把PID、模拟量处理这些功能块连起来,逻辑清晰。如果设备有明确的工作节拍和工序流程,比如注塑机、压装机、多工位转盘,SFC做主框架,各步的动作细节用梯形图或ST填充。如果涉及大量数据运算、坐标变换、通信报文解析,ST当主力,梯形图干体力活。
这里强调一下,很多人对SFC有误解,觉得它是用来替代梯形图的。其实SFC最适合做“骨架”,梯形图和FBD是“血肉”。我在做多工位装配线时,主逻辑用SFC描述各工位的顺序流转,每个工位内部的逻辑还是在“步”里用梯形图写,这样整个程序既有流程的宏观视野,又有逻辑的微观细节。
3.2 不同品牌的实现差异:别拿一个标准套所有PLC
虽然大家都说自己支持IEC 61131-3,但不同PLC品牌对五种语言的支持程度和实现风格差异不小。西门子的TIA Portal基本全支持,而且ST的语法表现很接近高级语言,博途里S7-Graph就是图形化的SFC实现,非常好用。三菱GX Works3也开始支持ST、FBD,但三菱的强项还是梯形图,其结构化编程体验相比西门子还是有点差距。汇川、信捷这些国产PLC,这几年走得很快,InoProShop就支持完整的IEC语言,基本逻辑就是围绕IEC 61131-3做的,代码复用率很高,这也是国产PLC进步的一个缩影。
所以学编程不能只学一套软件的操作,要理解IEC逻辑本身。你今天用惯了三菱的梯形图,明天跳到西门子S7-1500,只要IEC思维在,元素的摆放方式、指令的调用方式虽然不同,底层逻辑是通的。
3.3 程序结构怎么分:程序组织单元(POU)与功能块
说到混用语言,就绕不开IEC 61131-3里的另一个核心概念——程序组织单元(Program Organization Unit, POU)。它又分三种:函数(Function)、功能块(Function Block)、程序(Program)。函数没有内部状态,一样的输入得到一样的输出,适合写数学运算;功能块有记忆功能,每次调用会保持内部变量状态,适合封装定时器、计数器、PID这类需要“记住”上一次结果的处理逻辑;程序就是PLC主循环里的顶层执行单元。
我做个简单类比:函数就像你口袋里的计算器,按一次给一次结果;功能块就像有记忆的机器人,他记得上次走到哪里、上次数到多少,能基于历史状态继续干活;程序就像车间主任,负责调度人、机器、任务。具体到工程实现时,我们把每个工位定义为一个功能块,内部用ST或者FBD写具体算法,然后在主程序里调用。这样程序组织的结构非常清晰,调试时直接监控某一个FB的输入输出,效率特别高。
4. 深入细节:五种语言的核心语法与隐藏技巧
前面讲的都是整体思维,现在深入到每种语言的具体写法,拿典型例子展示实际代码和逻辑实现。这部分是纯干货,我会把每种语言的关键语法、编程习惯、容易出错的地方全部点透。
4.1 梯形图的深层操作:不只是画线圈
很多教程教你画电机启停,画完自锁互锁就没了。梯形图的功力其实体现在扫描顺序的理解上。PLC是循环扫描的,扫描周期内,梯形图按从上到下、从左到右的方式执行。这带来一个隐藏的问题——相同输出线圈不能被重复赋值,否则后者覆盖前者。这就是常见的Double Coil问题。
举个例子,设备报警输出Q0.0,你在梯形图第一段让它输出,又在第三十段再次输出,结果两个条件任何一个成立都会触发报警且状态不是你预期的。这在调试现场非常糟心——报警莫名其妙。所以好的习惯是:一个物理线圈在程序里只出现一次,其他逻辑用中间变量M来承接。
还有两个梯形图高频技巧:一是电机启动采用“启动优先”逻辑,即停止条件用常闭触点串联;二是急停用外部硬继电器接常闭点,不依赖PLC内部程序,这条涉及安全回路,不懂的人最容易犯,必须靠硬件兜底。再有,多设备连锁时,建议把“安全联锁”做成一个全局标志位:任何一台设备故障,置位故障标志,启动允许条件必须检查该标志位。这个思路哪怕用梯形图写,也能把程序维护成本降到最低。
4.2 FBD的结构化复用:从画图到“搭系统”
FBD要说细,核心还是功能块的封装和复用。你写一个电机控制FB,输入是启停按钮、故障信号、允许条件,输出是接触器线圈、故障输出、运行状态标志。然后项目里所有电机控制都调用这个FB,不仅程序代码量大幅下降,而且修改控制逻辑只需要改一个FB,所有实例同步更新,这个就是“复用”的魔力。
FBD的连线也需要讲究技巧。原则是数据流从左向右,控制流从上到下,模拟量信号和开关量信号分开区域布线。连线别交叉,实在有交叉的地方用跳线符号或网络标签。还有一个小技巧,FBD里每个功能块都要设置合理的“使能端(EN)”,在条件不满足时让功能块输出保持或者清零,这个处理在PID、累计器这类易受扫描周期影响的功能块中特别关键。
FBD若要做稍微复杂一点的模式切换,用“MUX”功能块做多路选择非常高效,比如“手动/自动”切换,把两套给定值作为输入,一个布尔变量选择输出哪一套——比用梯形图做切换的代码量少一半。
4.3 SFC的步进控制要点:别把SFC写成梯形图
SFC最关键的要素是步、转换条件和动作。一个步有两个状态:活动和不活动。当活动步的所有动作执行完毕且下一步的转换条件满足时,状态就跳到下一步。SFC编程有三个容易翻车的点。第一个是初始步:设备上电必须有一个初始化动作,别忘了初始化输出状态和让机械回到原点,否则第一刀就可能撞机。第二个是超时保护:设备在某个工位卡住了,机械手没到位,程序死等转换条件,如果没做超时报警,操作员根本不知道设备停在哪个环节。第三个是步的互斥性:SFC要求任意时刻只有一个活动步(除非用并行分支),不然逻辑就崩了。
SFC上手后,你会发现它最舒服的场景是“整个动作序列一目了然”。设备停了,看一眼当前活动步就知道它在等什么条件,调试和售后的沟通成本大幅下降。
4.4 结构化文本的实用写法:ST里的工程陷阱
这里给出一段ST代码示例,展示模拟量处理和报警判断的写法:
IF bManualMode THEN rSetpoint := rManualSetpoint; ELSE rSetpoint := rAutoSetpoint; END_IF; rError := rFeedback - rSetpoint; IF ABS(rError) > 10.0 THEN bDeviationAlarm := TRUE; ELSE bDeviationAlarm := FALSE; END_IF; IF rPV > rHighLimit OR rPV < rLowLimit THEN bProcessAlarm := TRUE; END_IFST要写得安全,有几个硬规矩。第一,变量命名要规范可读,用匈牙利命名法和功能前缀混搭,比如rFeedback表示浮点反馈,bManualMode表示手动模式布尔量,一眼看去就知道这个变量是什么。第二,除法运算前必须检查除数不为零,PLC和计算机一样,除零直接导致运行时错误。第三,ST里的CASE语句很好用,但如果变量类型是浮点数就尽量不要CASE,浮点比较误差很大,要用区间范围做判断。第四,循环语句谨慎用,扫描周期不允许长时间阻塞,如果要做大数据量的数组处理,确保循环次数可控,别把扫描周期拉到上百毫秒,不然运动控制的高响应就没了。
我自己的经验是,ST特别适合做通信协议解析。不管是Modbus报文、自由协议,数据帧解析就按字节来切,数组和FOR循环一配合,解析逻辑极其清晰。梯形图做这个,我能写哭。
4.5 IL的实用价值定位
IL的实际工程场景确实越来越少,但这不代表你完全用不到。在做老设备升级维护时,打开别人十年前写的IL程序,你得能看懂它在干嘛。IL是中间层语言,留下一些IL代码反而能最快弄懂老程序的动作逻辑。
另外,IL很小巧精炼,在一些微小型PLC和运动控制器里还有存在,学好IL不亏。关键是把操作符搞清楚:LD(装载)、AND(与)、OR(或)、OUT(输出)、SET/RST(置位/复位)、CMP(比较)、JMP(跳转)。这几种熟练掌握,看一般IL代码没压力。
5. 项目实战视角:从“翻译需求”到“选型落地”
光学会语法还不够,工程项目的核心是把“工艺需求”翻译成“程序逻辑”。这个翻译能力,恰恰是最难教的。这里我结合自己做非标设备的经验,走一个完整的项目思路。
5.1 从设备动作要求到程序架构设计
接到一个设备需求,比如一条小型装配线:自动上料、定位、锁螺丝、检测、下料,各工位独立又需要联动。我的第一件事不是写代码,是先做控制流程图。把设备有哪些传感器输入(光电开关、接近开关、编码器)、哪些执行输出(气缸阀岛、伺服电机、报警灯)、哪些工艺参数(速度设定、扭矩设定)全部列出来,做成一张I/O表,这是整个程序的地基。I/O表错了,后面全白干。
然后确定程序结构。这种多工位自动线,我倾向主框架用SFC,每个工位一个时序步;每个工位内部再写一个功能块,用ST处理位置、扭矩这些数值数据。这样的好处是:电气调试、售后维护、机构工程师核对动作流程的时候,都很舒服。
5.2 编程实操步骤记录:多工位装配线的逻辑实现片段
下面用一个简化版的关键步展示代码思想。假设2号工位是锁螺丝工位,流程包括:夹紧工件、伺服下压、电动螺丝刀拧紧、等待扭矩达到、抬起、松开工件。SFC里面大概是这样一个流程,那我用ST来写其中一个功能块的核心逻辑:
(* 锁螺丝工位核心逻辑 *) IF step = 2 AND bClampDone THEN bServoPress := TRUE; IF rTorque >= rTorqueSetpoint THEN bScrewDone := TRUE; bServoPress := FALSE; step := 10; (* 转到松开步 *) END_IF; END_IF这段例子最关键的是“扭矩达到”的判断,不单是数字对比。实际工况下扭矩会有波动,还经常出现“卡死——扭矩上升但角度不动”的异常情况。所以只判断扭矩是不够的,还要加一个角度增量超时判断。这里就能看到ST的优势:把两个判断条件同时在一个IF里处理,清晰高效。梯形图也能做,但代码会啰嗦不少。
5.3 手动模式、自动模式、报警逻辑怎么设计
程序不只是自动跑,手动模式同样重要,尤其是设备调试初期,手动能帮你把每一根线、每一个动作都验一遍。我的习惯是做一个总的手动/自动切换开关:手动模式下,所有自动动作全部禁止,执行器由面板按钮直接控制;自动模式下,程序按工艺顺序执行。这个互锁必须做得非常严密,不然机器人或者气缸在手动操作时误动作伤人,这是非常严重的安全风险。
报警逻辑建议独立编写一个报警功能块。把所有报警按类型分组:工艺报警(扭矩不足、定位偏差)、设备报警(气缸到位超时、伺服报警)、通信报警(上位机失去连接)。报警至少要有触发条件、保持/自锁、复位方式(按键复位、条件复位)。用ST写报警逻辑最好,数据可以用数组和结构体统一管理,HMI显示也方便。
6. 避坑指南:五年项目里踩过的典型坑
这部分是纯经验分享,每一种坑我都真实遇到过,写出来供大家参考。
6.1 环境与调试的坑
最经典的一个坑就是PLC与模拟屏不兼容的问题,比如某品牌PLC和某品牌HMI通信不上。一查发现是通信协议不一致,常见的是Modbus RTU和Modbus TCP混用,或者波特率、数据位、校验位设置不对。还有一个频率很高的坑是接线及端口设置——比如InoProShop在连接PLC时需要设置正确的通信端口,很多人默认设置不对就狂报错,其实是端口号、网络ID没配对。
排查思路我建议按这个顺序:先查通信物理链路(网线/串口线),再查配置文件里的端口号和网络ID,然后查PLC侧是否把该端口开放,最后查HMI侧是否建了相同的通信变量标签。大多数情况是参数没对上,不是硬件坏了。
还有一次项目里,博途PLC与模拟屏不兼容,设备老是断连。查了半天,发现是PLC侧通信负载过高,因为模拟屏在疯狂地读变量,而PLC又在同时做高速脉冲轴控制。最后我做了两件事:降低HMI的刷新频率,把非关键变量的刷新率降到500毫秒一次;把通信报文做了划分,重变量走专用通道。问题就解决了。
6.2 语言选择与程序维护的坑
我见过最惨的一个项目,程序是用梯形图写了几万个网络,一个设备逻辑穿插在几十个网络里,添加一个功能要翻上百页程序。这就是典型的“语言选型失误”——开关量逻辑确实梯形图直观,但复杂联动逻辑和状态管理必须用结构化语言来组织。
所以我的原则是:超过三个工位的联动机器人工作站,不建议无脑用梯形图铺开写;超过一个矩阵运算或坐标变换,不建议用非ST语言硬扛。程序可维护性是工程项目的生命线,设备运行三年后谁维护谁说了算。项目交付时,我会附一份程序结构说明文档,把POU结构、变量表、各FB的功能边界写清楚,方便后任维护工程师快速接手。
6.3 跟项目周期与PLC选型语言功能相关的一些话
现在国产PLC和中高端PLC的界限越来越模糊。汇川、信捷的编程软件都是IEC 61131-3体系,ST、FBD、梯形图混合编程都很成熟。所以在PLC选型时,语言支持能力也是重要指标。如果项目有大量数学运算和视觉通信需求,尽量选择对ST支持更好的品牌和型号。如果你是自动化毕业的学生,想选一门值得深耕的编程语言,ST的通用性和延展性确实最强——学会ST,你的思维方式可以直接过渡到高级语言。
7. 网上的常见提问速查:与我实际经验对照
下面整理几个网友高频问题,我和大家交流一下实际经验。
问:三菱PLC用ST编程到底值不值得学?我的体会是值得。虽然三菱的梯形图生态很强,但GX Works3对ST的支持已经很好了,数学运算和数据处理明显比梯形图省力。尤其做毕业设计或竞赛项目,ST能显著提升开发效率。
问:西门子博途到底用结构化文本还是梯形图?我的建议是看程序类型。逻辑控制为主用梯形图,数学处理和通信为主用ST,流程动作用S7-Graph,也就是SFC图形化实现。不要迷信最强大,要匹配最合适。
问:PLC编程入门基础知识最重要是哪块?我认为是“扫描周期”和“I/O寻址”这两个概念。不管用什么语言,不理解扫描周期,你写的时序逻辑一定是错的。先搞懂这两个基础,再谈语言细节。
问:温度PID波动温差大如何调节?这个问题项目里经常被问。我的建议是先抛开语言,检查参数:PID的采样周期、比例增益、积分时间是否匹配被控对象的惯性。温度对象大惯性,P值不能太大,积分时间不能太短,必要时加微分抑制超调。ST写PID参数自整定逻辑会方便很多。
8. 学习路径建议:从入门到混编高手的路线
如果你是从零开始学PLC编程,我建议按下面的顺序走,基本不会走弯路:
第一步,用梯形图建立基础。从电机的星三角降压启停开始,学会常开、常闭、线圈、定时器、计数器、置位复位。这个阶段的目标是懂逻辑、懂扫描、懂I/O映射。
第二步,玩FBD搭建模拟量系统。做一两个恒压供水或者温度控制,学会模拟量采集标定、PID闭环、上下限报警处理。
第三步,用ST处理算法数据。做一些坐标计算、数据排序、通信报文解析的小程序,彻底落一次ST的代码手感。
第四步,用SFC整合项目。自己搭一个多工位时序流程的项目,把前面学的所有功能细化装进去,体会“骨架”和“血肉”如何协调配合。
第五步,回头看标准和原理。回头认真读IEC 61131-3里程序组织单元、变量类型、执行控制的相关定义,你会发现很多应用层疑问迎刃而解。
每一步都配实际的上手操作,不要只看视频不敲指令。编程能力是用手练出来的,不是看出来的。
9. 我在实际项目里的几点体会
做PLC编程这一行,回头再看IEC 61131-3这五种语言,最大的体会是它们不是五种对手,而是一套组合拳。单用一种语言的人,就像工具箱里只有一把锤子,什么零件都敢砸一砸,但活干得糙。真正熟练的工程师,会根据场景随时换工具——开关量逻辑顺手就画梯形图,模拟量PID拉两个功能块连起来,复杂算法开个ST页面敲代码,流程顺序就用SFC做主轴结构。
有几次项目,我故意把同一个功能用两种语言实现,比如同样一个保压逻辑,第一版用梯形图,第二版用ST。对比下来,ST是更适合表达复杂工艺参数的,梯形图是更适合车间电工直观理解的。这个事让我印象特别深——你选语言不光是选工具,还是在选“这程序以后谁来接手维护”。设身处地为后面的维护工程师着想,选用的语言就会更克制、更有体系。
最后再分享一个小技巧:写大型PLC程序,一定给每个POU加上版本号和修改注释。哪怕是你自己,过了半年回头看你写的程序,没有注释也会头皮发麻。这个习惯用一句俗话说,就是“今天的注释,是明天的救命稻草”。