3. 程序块类型与职责划分

在西门子TIA Portal的S7-1200/1500编程体系中,程序块不是“代码文件的分类”,而是承载不同运行语义、数据生命周期和调用契约的工程对象。OB、FB、FC、DB四类块共同构成一个可执行、可复用、可维护的程序架构。理解它们的语义差异,比记住“OB是主程序、FB带背景数据”这类口诀更重要——因为选型错误往往不会立刻报错,而是在版本迭代、多实例调用或在线修改时集中暴露。

一、四类块的语义定位

OB(Organization Block,组织块)是CPU操作系统与用户程序之间的接口。它不由用户直接调用,而由系统在特定事件发生时触发,例如启动、循环扫描、时间中断、硬件中断、诊断中断等。OB1是默认的循环扫描组织块,其优先级最低,每个扫描周期执行一次。OB的职责是“调度入口”:把不同事件源映射到对应的处理逻辑,而不是承载大量业务算法。一个常见误区是把所有逻辑都塞进OB1,导致扫描周期波动、中断响应被拖慢。

FC(Function,函数)是无记忆的纯逻辑块。它没有背景数据块,输入参数在调用时传入,输出参数在返回时传出,内部临时变量(Temp)在每个扫描周期重新初始化。FC适合表达“给定输入必然得到确定输出”的运算、转换、判断和组合逻辑,例如量程换算、报警字解析、设备互锁条件计算。FC不保存状态,因此不能用于需要记住“上一次值”的场合。

FB(Function Block,功能块)是有记忆的逻辑块。它必须配合背景数据块(Instance DB)使用,静态变量(Static)存放在背景DB中,跨扫描周期保持。FB适合表达“有状态的对象”,例如电机、阀门、PID回路、配方步序。同一个FB可以被多次调用,每次调用分配不同的背景DB,从而形成多个独立实例——这就是“一个FB类型、多个设备实例”的复用模型。

DB(Data Block,数据块)是纯数据容器,分为全局DB和背景DB。全局DB由用户创建,存放共享数据,如配方参数、HMI交互区、报警阈值表;背景DB由FB调用时自动生成,存放该实例的静态变量和背景数据。DB本身不执行逻辑,但它的数据结构决定了FB的接口契约和版本兼容性。

OB / FB / FC / DB 调用关系与数据归属 OB 层 · 系统事件触发(不由用户调用) OB1 循环扫描 OB100 启动 OB30 循环中断 OB82 诊断中断 … 其它事件 FB / FC 层 · 用户逻辑(由OB或上层块调用) FB · 有记忆功能块 Static 变量跨周期保持 必须绑定背景DB 示例:电机控制、PID FC · 无记忆函数 Temp 每周期重新初始化 无背景DB,纯输入输出 示例:换算、互锁判断 FB 内嵌调用 FB 可调用 FC / 其它 FB 多层背景DB嵌套 注意实例DB层级 FC不产生背景DB DB 层 · 数据容器(不执行逻辑) 背景DB(Instance DB) 随FB调用生成 存放该实例Static数据 全局DB(Global DB) 用户手动创建 配方、HMI区、阈值表 多重背景 FB内声明Static为FB类型 减少独立DB数量 调用/触发 数据绑定 无背景DB

二、调用关系与数据归属

四类块的调用关系可以概括为:OB触发 → FB/FC执行 → DB承载数据。OB是唯一被系统调用的块;FB和FC由OB或上层FB调用;DB不参与调用,只被读写。需要特别注意的是,FC虽然不绑定背景DB,但它可以读写全局DB,因此“无记忆”指的是FC自身不保存状态,而不是它不能访问持久数据。

FB的调用必须指定背景DB。在TIA Portal中,当你在OB1中拖入一个FB时,系统会提示生成一个背景DB,命名通常为“FB名称_DB”。如果同一个FB被调用两次,必须使用两个不同的背景DB,否则两个实例会共享同一份静态数据,导致状态互相覆盖。这是初学者最常见的错误之一。例如,一个“电机控制FB”用于1号电机和2号电机,若共用同一个背景DB,则1号电机的运行标志会覆盖2号电机。

FB内部还可以调用其它FB,形成嵌套调用。此时被调用FB的背景DB可以作为调用者FB的静态变量存在,称为“多重背景”。多重背景的好处是减少独立DB数量,使实例关系更清晰;代价是背景DB的层级变深,在线监视时需要逐层展开。对于设备数量多、结构一致的产线,多重背景是更优的组织方式。

三、选型准则:什么逻辑放什么块

选型的第一判断是“是否需要记住上一次的值”。需要记忆的,用FB;不需要记忆的,用FC。第二判断是“是否被多个对象复用”。如果同一段逻辑要用于多台设备,用FB加不同背景DB,或FC加不同输入参数。第三判断是“是否由系统事件触发”。只有需要独立响应启动、中断、诊断等事件的逻辑,才单独建立OB;普通循环逻辑放在OB1调用的FB/FC中即可。

一个实用的选型顺序是:先识别设备对象,为每个有状态的设备建立FB;再识别公共运算,建立FC;然后识别共享数据,建立全局DB;最后在OB1中按工艺顺序调用FB和FC,并处理启动OB和中断OB。这样得到的程序结构,块职责清晰,后续增加设备时只需增加背景DB和调用,不需要修改已有逻辑。

选型速记:有状态、要复用 → FB + 背景DB;纯运算、无状态 → FC;共享参数、HMI交互 → 全局DB;系统事件入口 → OB。不要用FC模拟状态保持,也不要把所有逻辑堆在OB1。

四、示例:电机控制块的选型与调用

假设一条产线有3台电机,每台需要启停控制、运行反馈、故障报警和累计运行时间。累计运行时间需要跨周期保持,因此必须用FB。定义FB“MotorCtrl”,接口如下:Input:Start、Stop、Fault;Output:Run、Alarm;InOut:RunHours;Static:RunFlag、FaultLatch。在OB1中调用三次,分别绑定背景DB“Motor1_DB”“Motor2_DB”“Motor3_DB”。

// OB1 中的调用示意(梯形图或SCL)
"Motor1_DB"(Start := "I0.0", Stop := "I0.1", Fault := "I0.2",
            Run => "Q0.0", Alarm => "Q0.1",
            RunHours := "DB_Global".Motor1Hours);

"Motor2_DB"(Start := "I0.3", Stop := "I0.4", Fault := "I0.5",
            Run => "Q0.2", Alarm => "Q0.3",
            RunHours := "DB_Global".Motor2Hours);

这里“Motor1_DB”和“Motor2_DB”是同一个FB类型的不同实例,各自保存RunFlag和FaultLatch,互不影响。RunHours放在全局DB中,是因为它需要被HMI读取和归档,属于共享数据。如果后续增加第4台电机,只需复制调用并新建背景DB,FB内部逻辑无需改动。

五、常见误区与版本治理关联

第一个误区是“FB背景DB可以随便换”。背景DB的结构由FB接口决定,如果修改FB的Static变量,背景DB需要同步更新,否则在线下载时可能触发一致性错误。第二个误区是“FC可以替代FB”。FC的Temp变量在每个周期重新初始化,用它做状态保持会导致逻辑时好时坏。第三个误区是“全局DB越多越好”。全局DB过多会导致数据归属模糊,版本升级时难以判断哪些数据被哪些块使用。

从版本治理角度看,FB的接口变更影响最大,因为它牵连所有背景DB和调用点;FC的接口变更影响调用点,但不涉及背景DB;OB的变更通常只影响触发逻辑;全局DB的变更影响所有读写它的块。因此,在程序架构设计阶段,应尽量稳定FB接口,把易变参数放入全局DB或FB的Input,而不是频繁修改Static结构。这样在后续版本迭代中,程序块的兼容性和可维护性都会显著提升。