1. 从梯形图到SFC:为什么我们需要另一种编程语言?
如果你接触过PLC编程,尤其是西门子、三菱这些主流品牌,那你对梯形图(LAD)一定不陌生。它直观、形象,用继电器触点、线圈的逻辑关系来构建程序,对于电工出身的工程师来说,上手门槛极低。我刚开始做项目时,也觉得梯形图就是一切,直到我遇到了一个中等复杂度的灌装生产线项目。
那条线有十几个工位,包含上料、清洗、灌装、封盖、贴标、检测、分流等多个工序,工序之间有严格的顺序和条件互锁。用梯形图硬撸,我画了上百个网络段,各种中间继电器(M点)用了好几百个,程序结构像一团乱麻。调试时,某个工位的一个传感器故障,导致整条线停机,我要花半个多小时在成百上千条逻辑里“顺藤摸瓜”找问题。更头疼的是,客户要求增加一个抽检和返工回路,我几乎要推倒重来一半的逻辑。那时我才深刻体会到,梯形图在处理复杂的顺序控制流程时,就像用螺丝刀去拧一颗需要扳手的大螺母——不是不能用,是效率太低,且容易出错。
这时,SFC(Sequential Function Chart,顺序功能图)就登场了。它不是来取代梯形图或语句表(STL)的,而是来补足它们的短板。你可以把SFC理解为给PLC程序画“流程图”或“工艺路线图”。它用“步”(Step)和“转移”(Transition)这两个核心元素,清晰地描绘出设备或工艺从一个状态切换到另一个状态的完整过程。每一步代表一个稳定的工艺状态(比如“夹紧气缸伸出”、“主轴旋转”),转移条件则是触发状态切换的开关(比如“气缸伸出到位信号”、“启动按钮按下”)。
对于前面提到的灌装线,用SFC来编程,整个流程就一目了然:一个初始步,然后按顺序是“上料步”、“清洗步”、“灌装步”……每一步下面挂载具体的动作输出(用梯形图或功能块实现),步与步之间用转移条件连接(比如“物料到位传感器=1”)。程序执行时,就像一个指针,严格按照这张图一步一步往下走。哪个工位出了问题,直接看程序指针停在哪一步,问题瞬间定位。要增加返工流程?只需要在SFC图中插入一个选择分支,指向返工步序列即可,原有主流程几乎不用动。
所以,SFC编程的核心价值在于:它将控制逻辑(做什么,按什么顺序做)与控制动作(具体怎么做)进行了清晰分离。逻辑部分由直观的图表负责,动作部分则由你熟悉的梯形图、功能块等负责。这种结构特别适合具有明显顺序、并行、选择分支的工业过程控制,比如装配线、包装机械、物料输送系统等。它让程序的可读性、可维护性和可扩展性得到了质的提升。
2. SFC的核心三要素:步、转移与有向连线
要玩转SFC,必须吃透它的三个基本构件:步(Step)、转移(Transition)和有向连线(Directed Link)。这就像学英语要先掌握字母一样。
2.1 步(Step):工艺的稳定状态
步,在SFC图中通常用一个方框表示,里面标上步的名称或编号(比如S0, S10)。它代表控制系统中的一个稳定工作阶段或状态。在这个阶段内,系统执行一系列连续的动作,并且输出状态保持相对不变。
步分为两种:
- 活动步(Active Step):当前正在执行的步。一个SFC程序在任意时刻,至少有一个活动步(初始步)。活动步意味着它所关联的动作或命令正在被执行。
- 非活动步(Inactive Step):当前未执行的步。它关联的动作不被执行。
这里有一个关键概念:步本身不执行具体操作。它只是一个“状态标签”。具体的操作,比如“启动电机M1”、“打开阀门YV1”,是通过与步关联的“动作”(Action)来完成的。在西门子S7-1200/1500的SCL或S7-300/400的GRAPH中,你可以在步的属性里添加动作,并指定动作类型(比如“N”非存储型,“S”置位型等)。
一个实用的经验:给步命名时,尽量使用描述其工艺状态的名称,如“Wait_For_Part”(等待工件)、“Clamping”(夹紧)、“Drilling”(钻孔),而不是简单的S1, S2。这在调试和后期维护时,能让你和你的同事一眼看懂程序在干什么。
2.2 转移(Transition):状态切换的闸门
转移,是连接两个步的短横线,通常上面或旁边会标注转移条件。它代表了从一个步切换到下一个步必须满足的条件。只有当转移条件为“真”(TRUE)时,系统才会离开当前的活动步,进入后续步。
转移条件可以是简单的布尔逻辑(如“I0.0 AND I0.1”),也可以是复杂的表达式或函数调用结果。它就像是流程前进的“通行证”。
一个极易踩坑的点:转移条件的“瞬态”特性。在PLC的扫描周期中,转移条件通常只在被扫描到的那一瞬间被评估。如果条件是一个短暂的脉冲信号(比如一个按钮的上升沿),你必须确保这个脉冲能够被SFC程序捕捉到。一种常见的做法是,在梯形图里用这个脉冲信号置位一个中间标志位(M点),然后用这个标志位作为SFC的转移条件,并在转移完成后在SFC内或梯形图里复位该标志位。否则,你可能遇到流程“卡住”不走,或者莫名其妙跳步的情况。
2.3 有向连线(Directed Link):流程的方向
有向连线就是带箭头的线,它指明了流程的方向,即从上一个步经过转移,指向下一个步。它定义了控制的顺序。
这三者结合起来,就构成了SFC最基本的单元:步 → 转移 → 步。程序从初始步开始,沿着有向连线,根据转移条件的满足情况,一步一步地推进。
3. SFC的三种基本结构:单序列、选择分支与并行分支
掌握了基本元素,我们来看它们如何组合成控制逻辑的骨架。SFC主要有三种基本结构,几乎可以描述所有顺序控制过程。
3.1 单序列(Single Sequence)
这是最简单、最常用的结构,就是一系列步和转移按顺序串行连接。流程严格地一步接一步执行,只有前一步完成且转移条件满足,才能进入下一步。就像流水线上的一个工位干完活,工件才能流到下一个工位。
[初始步 S0] --(启动按钮按下)--> [步 S1: 传送带前进] --(到达位置A)--> [步 S2: 气缸下降] --(下降到位)--> [步 S3: ...]适用场景:简单的顺序过程,如单机设备的基本动作流程。
3.2 选择分支(Selection Branch)
选择分支表示流程在此处可能出现多个可能的后续路径,但每次只选择其中一条路径执行。分支的入口和出口都有一个转移。入口转移称为“选择开始”,出口转移称为“选择结束”或“合并”。
[步 S10: 检测工件] | |--(工件合格)--> [步 S11: 送入合格品线] | |--(工件不合格)--> [步 S12: 送入返修线] | |--(无工件)--> [步 S13: 报警等待] | (选择合并)--> [步 S20: 流程继续...]关键点:分支的优先级。在大多数PLC的SFC实现中(如西门子GRAPH),当多个分支的转移条件同时为真时,会按照分支绘制的先后顺序(通常是从左到右,或从上到下)选择第一个条件为真的分支执行。这在编程时必须考虑清楚,避免逻辑歧义。例如,上面例子中,“无工件”和“工件不合格”如果同时满足(理论上不合理,但可能因传感器故障导致),就需要根据优先级决定先处理哪个报警。
3.3 并行分支(Parallel Branch)
并行分支表示流程在此处分裂成多个同时执行的路径,这些路径是并发进行的。所有并行分支都执行完毕后,流程才会同步合并,继续向下执行。入口处是一个双横线,表示分支开始;出口处也是一个双横线,表示同步合并。
[步 S30: 准备装配] || ||------------------> [步 S31: 安装零件A] --(完成)--> | || | (同步合并) ||------------------> [步 S32: 安装零件B] --(完成)--> | || [步 S40: 总装检验]核心规则:所有并行分支必须全部执行到各自的最后一步,并且所有分支最后的转移条件都满足后,同步合并处的转移才被视为满足,流程才能汇合继续。这是实现多工位同步协调的关键机制。
一个重要的实践经验:在并行分支中,尽量避免某个分支的流程步数远多于其他分支。如果无法避免,可以在步数少的分支最后增加“等待步”,直到所有分支都准备好再同步。否则,步数少的分支会早早执行完并在合并点等待,如果等待时间过长,可能会因看门狗或意外情况导致问题。
4. 在西门子TIA Portal中实现一个SFC案例:物料分拣装置
光说不练假把式,我们用一个经典的PLC实训项目——物料分拣装置——来实战SFC编程。假设装置流程如下:启动后,传送带运行,检测到物料后,根据颜色传感器信号(假设I0.0为黑色,I0.1为白色),将黑色物料推入A槽,白色物料推入B槽,然后循环。
我们使用西门子S7-1200 PLC和TIA Portal V17环境。注意,S7-1200/1500中,SFC功能主要通过“GRAPH”或“SCL”语言实现,这里我们用更直观的GRAPH(属于FBD/LAD/STL之外的另一种编程语言,专用于顺序控制)。
4.1 项目创建与硬件组态
- 打开TIA Portal,新建项目,添加一台S7-1200 CPU(如1214C)。
- 在设备视图中,根据实际需求添加数字量输入/输出模块。假设:
- I0.0: 黑色物料检测
- I0.1: 白色物料检测
- I0.2: 物料到达推杆位置检测
- I0.3: 启动按钮(常开)
- I0.4: 停止按钮(常闭)
- Q0.0: 传送带电机
- Q0.1: 推杆A电磁阀
- Q0.2: 推杆B电磁阀
- 在“程序块”中,添加一个新的块。类型选择“函数块(FB)”,语言选择“GRAPH”。命名为“FB_Material_Sort”。这将是我们SFC程序的主体。
4.2 设计SFC程序结构
打开GRAPH编辑器,我们会看到初始界面。GRAPH的编辑区就是用来画SFC图的。
- 初始步(S1): 系统上电后的等待状态。通常命名为“Initial”或“Wait_Start”。在这个步里,我们不执行任何动作,或者只执行一些初始化操作(如复位所有输出)。转移条件为“启动按钮按下”(I0.3)。
- 运行步(S2): 进入运行状态。动作:激活传送带(Q0.0 = 1)。转移条件:物料到达推杆位置(I0.2)。
- 选择分支开始: 在S2之后,我们建立一个选择分支,根据物料颜色决定流向。
- 分支1(黑色): 转移条件:I0.2 AND I0.0(物料到位且是黑色)。步S3:动作:推杆A推出(Q0.1 = 1),并启动一个定时器(T1)用于推杆保持。转移条件:定时器T1到时。
- 分支2(白色): 转移条件:I0.2 AND I0.1(物料到位且是白色)。步S4:动作:推杆B推出(Q0.2 = 1),启动定时器T2。转移条件:定时器T2到时。
- 选择分支合并: S3和S4之后,合并到同一个步S5。
- 复位步(S5): 动作:复位推杆A和B(Q0.1=0, Q0.2=0),同时复位用于分支判断的中间标志位(如果有的话)。转移条件:推杆复位到位(可以加传感器,或用一个短延时T3)。满足后,转移回步S2(传送带运行),形成循环。
4.3 GRAPH中的关键设置与编程技巧
在GRAPH中编辑时,有几个细节需要特别注意:
- 互锁(Interlock): 可以在步的属性中设置“互锁”条件。当互锁条件为假时,即使该步是活动步,其关联的动作也不会执行。这常用于急停、安全门等安全功能。例如,在S2(传送带运行)的互锁条件中加上“停止按钮(I0.4)”,这样按下停止,传送带立即停。
- 监控(Supervision): 也叫监督条件。如果监控条件为真,会触发一个监控事件,可以强制跳到指定的步(通常是错误处理步)。这用于处理超时、卡料等故障。例如,在S2可以加一个监控定时器,如果物料在设定时间内未到达位置(I0.2未触发),则跳转到报警步。
- 动作的限定符: GRAPH中动作前面可以加限定符,如:
- N(Non-stored): 非存储型。步活动时动作执行,步不活动时动作停止。最常用。
- S(Set): 置位型。步活动时置位一个位,该位会保持,直到被其他地方复位。
- R(Reset): 复位型。步活动时复位一个位。
- L(Time Limited): 时间限制型。动作只执行一段设定的时间。
- D(Time Delayed): 时间延迟型。步活动后延迟一段时间再执行动作。 合理使用限定符可以简化程序。比如推杆动作,用“N”型,步激活就推出,步关闭就缩回。但如果推杆需要保持到下一个周期,则可能需要用“S”型,并在后续步中用“R”型复位。
- 使用“接口”变量: 在FB的“接口”区定义好Input、Output、InOut、Static、Temp变量。将传感器信号(I点)连接到Input,执行器(Q点)连接到Output。在GRAPH内部使用这些接口变量,而不是直接使用绝对地址(如I0.0)。这提高了块的可重用性和可读性。
4.4 在OB1中调用与调试
- 在组织块OB1(主循环)中,拖入我们创建好的FB“FB_Material_Sort”。需要为其指定一个背景数据块(Instance DB),比如“DB_Material_Sort”。
- 将实际的PLC输入输出地址,连接到FB的输入输出管脚。
- 下载程序到PLC。
- 在线监控GRAPH程序。这是最爽的时刻:你可以清晰地看到一个活动步指针在SFC图上移动,直观地展示程序执行到了哪一步。哪个转移条件不满足,也会高亮显示。调试效率比在梯形图里大海捞针高得多。
5. SFC编程的进阶技巧与常见避坑指南
掌握了基础,我们聊聊那些手册上不常写,但实践中血泪换来的经验。
5.1 步与动作的分离设计哲学
这是用好SFC的精髓。步,只做状态管理和流程控制;具体的、复杂的逻辑和运算,交给专用的功能块(FC/FB)去完成。例如,在一个“温度控制步”中,不要试图在步的动作里写一整套PID算法。你应该在步的动作里,调用一个已经编写好的“PID_Control”功能块,并传递设定值和过程值参数。SFC步只负责在需要时启动这个PID控制,并在转移到下一步时停止它。这样,SFC图保持清晰,功能块可以独立测试和复用。
5.2 并行分支的同步与异步问题处理
并行分支的同步合并要求所有分支都完成,这在某些场景下可能过于严格。例如,一个装配工位有两条并行送料线,但允许其中一条线暂时缺料,另一条线先完成装配的半成品可以暂存等待。这时,严格的同步合并就不合适了。
解决方案:可以使用“先完成等待”机制。即,在每个并行分支的最后一步,不直接指向同步合并点,而是指向一个“等待同步”步。在这个等待步里,程序检查其他分支的状态。我们可以定义一个共享的“同步请求”标志数组。当某个分支完成时,将其对应的标志位置位。在等待步里,检查是否所有需要的标志位都被置位(或者根据更灵活的逻辑判断)。满足条件后,再转移到真正的合并后步骤。这样,你就实现了可配置的、灵活的同步逻辑。
5.3 跳出循环:如何优雅地处理急停、复位与模式切换
这是SFC设计中的难点。设备不可能永远自动循环,需要有手动模式、急停、复位等功能。粗暴地在任何地方切断SFC流程会导致状态混乱。
推荐模式:
- 模式信号全局化: 定义一个全局变量(如“Mode_Manual”),在手动模式下为True。在SFC每一个步的互锁(Interlock)条件中,都加入“NOT Mode_Manual”。这样,一旦切换到手动模式,所有步的动作输出立即失效(但步的状态可能还保留),你可以通过手动按钮控制设备。
- 急停处理: 急停信号同样作为全局互锁条件,加入到每一步。同时,急停发生时,通常需要跳转到一个特定的“急停处理步”。这个步负责安全地停止所有运动部件,并复位一些关键状态。可以在GRAPH的“Supervision”中,将急停信号作为监控条件,直接跳转到“急停步”。
- 复位与初始化: 设计一个独立的“初始化”SFC序列,或者一个专用的“复位”功能。当收到复位命令时,不是简单地让SFC从头开始(可能导致中间步动作紊乱),而是先执行一个“安全停止序列”,将所有输出置于安全状态,然后使用GRAPH提供的“禁用顺控器”或“直接跳转到初始步”指令,将主SFC流程重置。西门子GRAPH中有“SFC控制”指令,如
SFC_START,SFC_STOP等,可以用来在外部控制SFC的启停和重置。
5.4 调试与诊断:利用活动步信息快速定位故障
SFC最大的调试优势就是可视化。在线时,活动步高亮显示。当设备停机时,第一件事就是看SFC图停在哪一步。
- 卡在某个步不动: 检查该步到下一步的转移条件是否满足。在线监控转移条件的布尔逻辑,看哪个信号没到位。
- 流程乱跳: 检查是否有多个转移条件意外同时为真,尤其是在选择分支中。检查传感器信号是否抖动,导致条件瞬间满足。可以考虑在转移条件中加入上升沿判断或短延时滤波。
- 动作输出异常: 步是活动的,但输出没动作。检查该步的动作是否被正确编程,动作的限定符是否合适,以及互锁条件是否阻止了动作输出。
- 使用GRAPH的“序列器”视图: TIA Portal的GRAPH在线视图,除了图形化显示,还有一个“序列器”列表视图,它以表格形式列出所有步的状态、活动时间、转移条件值等,信息更集中,便于分析。
6. SFC与其他PLC编程语言的协同与比较
SFC不是孤岛,它需要与其他IEC 61131-3标准语言(如LAD, FBD, STL, SCL)协同工作,才能发挥最大威力。
6.1 与梯形图(LAD)/功能块图(FBD)的配合
这是最常见的组合。SFC负责高层级的流程调度,而每一步里具体的、底层的逻辑,则用LAD或FBD来实现。例如:
- 电机启停控制: 在SFC的“启动电机”步中,调用一个用LAD编写的“电机控制”功能块,该功能块集成了启动、停止、互锁、过载保护等逻辑。
- 模拟量处理: 在SFC的“数据采集”步中,调用FBD编写的模拟量输入缩放和滤波功能块。
这种分工明确,SFC程序简洁,底层逻辑模块化,易于复用和测试。
6.2 与结构化文本(STL/SCL)的配合
对于涉及复杂计算、数据处理、字符串操作或数组遍历的任务,SCL(西门子)或ST(其他品牌)比图形化语言更高效。SFC可以与它们无缝配合:
- 配方管理: 在SFC的“加载配方”步中,调用一个SCL函数,该函数从DB块或HMI读取一组参数,并赋值给相应的工艺变量。
- 数据记录: 在“生产完成”步中,调用SCL函数将生产数据(时间、数量、质量参数)写入数据库或SD卡。
SCL的强大运算能力,弥补了SFC在复杂数据处理方面的不足。
6.3 不同品牌PLC的SFC实现差异
虽然IEC 61131-3标准定义了SFC,但各厂商的实现细节有差异,这是跨平台移植时的主要障碍。
- 西门子(S7-300/400, S7-1200/1500): 早期S7-300/400使用“GRAPH 7”语言,集成在Step 7中。S7-1200/1500在TIA Portal中使用“GRAPH”,功能更现代。特点是功能强大,互锁、监控、动作限定符齐全,在线调试直观。但语法和结构与标准SFC略有不同。
- 三菱(MELSEC系列): 使用“SFC(顺序功能图)”编程语言,其理念更贴近标准。它用“状态继电器(S)”来表示步,用“SET”和“STL”指令来激活步和驱动步内逻辑。编程思维是“步进梯形图”,对于熟悉三菱梯形图的工程师来说过渡平滑。
- 罗克韦尔(AB): 在RSLogix 5000/Studio 5000中,通过“顺序功能图(SFC)”例程来实现。它也是一个独立的编程语言环境,概念与标准一致。
- 汇川、信捷等国产PLC: 大多也支持SFC编程,通常借鉴了三菱或西门子的模式。需要查阅具体型号的手册。
移植经验: 从一个平台迁移SFC程序到另一个平台,几乎不可能直接转换。最好的方法是重新设计。基于原有的工艺流程图和控制逻辑,在新平台上用其SFC工具重新实现。核心的步、转移、分支结构可以保留,但具体的动作编程、变量定义、特殊功能(如跳转、复位)都需要按照新平台的规则重写。
7. 从实训到实战:复杂项目中的SFC架构设计
当面对一个拥有多个子系统、多种工作模式(自动、手动、维修、配方)的大型项目时,单个SFC程序会变得异常庞大和难以管理。这时,就需要考虑SFC的架构设计。
7.1 分层式SFC设计
这是最有效的架构之一。将整个控制系统划分为多个层次:
- 主控层(Master SFC): 这是一个顶层的SFC,负责整个系统的工作模式切换(自动、手动、停机等)和主要生产阶段的调度(如“上料”、“加工”、“装配”、“下料”)。它的每一步,可能对应一个子系统的启动。
- 子系统层(Sub-system SFC): 每个主要的设备单元或功能模块(如机器人单元、传送带系统、加热炉)都有自己的SFC程序。这些子SFC作为功能块(FB)被主控SFC调用。当主控SFC进入“加工”步时,它调用“加工单元_SFC”FB,并启动该子流程。
- 设备层(Device Level Logic): 在子SFC的每一步中,具体的动作由底层的梯形图、功能块图或SCL程序实现。
这种分层结构清晰,职责分明。调试时,可以单独测试和模拟每个子SFC。修改某个子系统时,不会影响到主流程和其他子系统。
7.2 状态机与SFC的结合
对于非纯顺序,而是有多个状态来回切换的复杂设备(如一台有“待机”、“准备”、“运行”、“暂停”、“故障”等多种状态的机床),可以结合状态机思想。
我们可以设计一个核心的“设备状态机”,用枚举变量(如Device_State: (IDLE, PREPARE, RUN, PAUSE, FAULT))来表示。这个状态机的迁移由各种事件(按钮、传感器信号、SFC完成信号)触发。
然后,SFC程序可以基于这个“设备状态”来运行。例如,只有当Device_State == RUN时,主生产SFC才被激活执行。当发生故障时,Device_State跳转到FAULT,这会触发SFC中的监控条件,使其跳转到故障处理步,同时所有步的互锁条件因Device_State != RUN而失效,确保安全。
7.3 配方与参数管理
在需要生产不同产品(配方)的场景下,SFC的流程可能大同小异,但参数(如温度、时间、速度)不同。好的设计是将SFC流程模板化,参数变量化。
- 在SFC中,所有与配方相关的设定值(如定时器时间、模拟量输出值)都使用变量(如
Set_Temperature,Heat_Time),而不是直接写常数。 - 创建一个配方数据块(DB),里面为每个配方定义一组参数结构。
- 在HMI或上位机选择配方后,将对应配方的参数结构体数据,整体复制到SFC程序使用的当前配方变量区。
- SFC程序运行时,使用的就是当前配方载入的参数。
这样,增加一个新配方,只需要在配方DB里新增一组数据,无需修改SFC程序逻辑,极大地提高了灵活性。
从我第一次被梯形图的“面条式”代码折磨,到后来在多个大型产线项目中运用分层SFC架构游刃有余,这个过程让我深刻认识到,选择合适的编程范式对于工程效率和系统可靠性的重要性。SFC不仅仅是一种语言,更是一种结构化、可视化的设计思想。它强迫你在动手写代码之前,先想清楚设备的整个工作流程和状态变迁,而这正是做出稳定、易维护的PLC程序的关键。刚开始画SFC图可能会觉得有点麻烦,不如直接写梯形图来得“快”,但当你面对调试、修改和交接文档时,前期的这点投入会带来成倍的回报。下次当你面对一个复杂的顺序控制任务时,不妨先拿起笔,画一画它的SFC图,你会发现,问题变得清晰多了。