博途 SCL 转梯形图实用指南

本指南记录了实际的工程路径:(1) TIA Portal 可以自动转换的内容;(2) 必须手动转换的模式;(3) 应该使用纯 LAD 重新实现而不是强制实现的模式;以及 (4) 验证新代码功能等效性的步骤。

博途 SCL 转梯形图实用指南
梯形图转SCL | 需求文本转SCL | 梯形图在线查看 | 博途编程文档MCP | AI模型价格对比 | AI工具导航 | ONNX模型库 | Vibe Coding教程 | PLC在线仿真器 | Tripo 3D | Meshy AI | ElevenLabs | KlingAI | ArtSpace

SCL(结构化控制语言)是西门子对 IEC 61131-3 结构化文本的品牌名称。梯形图 (LAD) 是一种基于图形化、扫描式的语言,围绕触点、线圈和并联/串行分支构建。它们并非同一逻辑的等效表示,西门子也没有发布适用于通用代码的无损 SCL 到 LAD 编译器。 TIA Portal 提供了一个“源到 LAD”显示选项,可以根据编译后的 SCL 重新生成 LAD 视图,但它仅适用于一小部分语句,对于其他所有语句,都会默默地回退到“无法生成 LAD 表示”的占位符。

本指南记录了实际的工程路径:(1) TIA Portal 可以自动转换的内容;(2) 必须手动转换的模式;(3) 应该使用纯 LAD 重新实现而不是强制实现的模式;以及 (4) 验证新代码功能等效性的步骤。示例适用于 TIA Portal V17/V18/V19 中的 S7-1200/S7-1500 固件 V4.x 和 V5.x。

工程实际情况:预计任何非平凡的 SCL 代码块中,60-90% 的内容都需要手动转换。“一键转换”工作流程仅适用于简单的赋值语句、布尔 AND/OR 语句以及少数算术语句。对于循环、CASE 语句、指针、AT 变体、多实例数据库访问和字符串处理,您必须要么将逻辑重写为 LAD 格式,要么将代码块保留在 SCL 格式中并记录边界。

0、前提条件

  • 软件:TIA Portal V17、V18 或 V19,并需具备 STEP 7 专业版许可证。较早版本的 STEP 7 V5.x(SIMATIC Manager)对 SCL→LAD 的处理方式不同,西门子常见问题解答中提供了关于 SCL/STL/LAD 切换的说明。
  • 硬件目标:S7-1200(CPU 121x/1215/1217)或 S7-1500(CPU 151x/1515/1516/1518)。S7-300/400 SCL 编译器接受略有不同的语法子集。
  • 原始 SCL 源文件:如果项目仅包含已编译的块(没有源文件),请在尝试转换之前使用“项目 → 源文件 → 导出”,因为 LAD 生成器需要的是 SCL 源文件,而不是已编译的 STL 文件。
  • 块接口:读取 FB/FC 的 INPUT、OUTPUT、IN_OUT、STATIC 和 TEMP 部分。这些部分将直接转换为 LAD 网络标签和 I/O 触点。
  • 测试环境:目标 CPU 的 S7-PLCSIM 实例,固件版本与目标 CPU 相同。您将在最后一节的等效性测试中用到它。

1、确定哪些内容可以自动转换

在 TIA Portal 中打开 SCL 块,在编辑器中右键单击并选择“显示为 LAD”(或使用状态栏中的语言选择器)。编译器将根据下表中的规则评估每个语句。

常用 SCL 语句的自动转换能力

‌                             SCL 语句 是否支持自动 LAD 注释     a := b AND c; 是 串行触点,单网络   a := b OR c; 是 并行分支   a := NOT b; 是 反向触点   a := b XOR c; 是 实现为并行常闭触点   a := b;(布尔值) 是 直接线圈分配   IF ... THEN ... END_IF;(单分支,无 ELSE) 是 每个分支都成为一个带有记忆位的网络   IF ... THEN ... ELSE ... END_IF; 部分支持 THEN 分支转换;ELSE 分支仅当不包含嵌套的 SCL 时才转换   CASE x OF ... END_CASE; 否 显示“无法使用 LAD 表示”;需要手动重写   FOR i := 1 TO 10 DO ... END_FOR; 否 循环无法用基于扫描的 LAD 表示   WHILE ... DO ... END_WHILE; 否 与 FOR 相同的限制   数组索引 a[i] 受限 仅常量索引或符号循环计数器会失效   使用 P# / PEEK / POKE 进行间接寻址 否 基于指针的访问没有对应的 LAD 实现   STRING / WSTRING 操作 否 保留在 SCL 中或移至专用的 STRING FC   AT 变体视图(基于标签) 否 使用单独的数据库并命名字段替换

任何标记为“否”的内容都必须手动翻译。策略是在失败的语句边界处断开 SCL 块,仅转换可转换的前缀;其余部分作为 SCL 调用保留在新的包装块中。

性能提示:TIA Portal 的“显示为 LAD”功能是一个视图,而不是一个新程序。关闭并重新打开块不会保存 LAD 版本。要创建永久的 LAD 副本,您必须添加一个新的 LAD 块,手动粘贴转换后的网络,然后重新验证。

2、将 SCL 接口映射到 LAD 符号

每个 VAR_INPUT、VAR_OUTPUT、VAR_IN_OUT 和 VAR_TEMP 都直接成为触点或线圈操作数。下表显示了典型 FB 的映射。

‌                             SCL 声明 LAD 操作数映射 LAD 使用示例     VAR_INPUT bEnable : BOOL; END_VAR 无触点,扫描输入 bEnable(默认符号) bEnable → 触点   VAR_IN_OUT iValue : INT; END_VAR 触点 + 线圈对(读-修改-写) "iValue" 在一个网络中被引用两次   VAR_OUTPUT bReady : BOOL; END_VAR 输出线圈 =( ) "bReady" → 输出线圈   VAR_STATIC sState : INT; END_VAR 来自实例数据库 "MyFB" 的静态内存位/标签(多实例:#sState#sState   VAR_TEMP tIdx : INT; END_VAR 本地临时标签 梯形符号 #tIdx 仅用作 MOV 输入

对于多实例 FB,# 前缀解析为包含它的实例数据库。在单个 FB 中,使用井号访问本地值;在全局 FC 中,必须先将其分配给全局标签或静态数据库标签。

3、转换赋值语句和布尔表达式

从最简单的 SCL 形式开始:单个布尔赋值语句。

SCL 源码:

‌                   IF bStart AND NOT bStop THEN bMotor := TRUE; ELSE bMotor := FALSE; END_IF;

等效的 LAD 网络(单网络,输出线圈):

‌                   |   bStart   |   /bStop   |   bMotor    | |-----| |----------|/|----------( )-----|

两个触点串联:bStart 为常开触点,bStop 为常闭触点(注意符号中的斜杠)。当两个触点都为真时,线圈通电。

4、将 IF/ELSIF/ELSE 链转换为互斥网络

自动转换器仅处理单个 IF 语句。手动转换 ELSIF 梯形图需要为每个分支创建一个网络,并使用内存位锁定来确保分支互斥。

SCL 源码:

IF iMode = 1 THEN
   bManual := TRUE;
   bAuto   := FALSE;
ELSIF iMode = 2 THEN
   bManual := FALSE;
   bAuto   := TRUE;
ELSE
   bManual := FALSE;
   bAuto   := FALSE;
END_IF;

LAD 策略:使用 EQ_I(整数比较)触点,在第一个分支中设置为 1,在第二个分支中设置为 2。第三个分支是隐式默认值(没有条件为真)。

网络 1(手动):

|   iMode == 1   |   bManual   |
|---[CMP==]------|---(S)-------|
|                |   bAuto     |
|----------------|---(R)-------|

网络 2(自动):

|   iMode == 2   |   bManual   |
|---[CMP==]------|---(R)-------|
|                |   bAuto     |
|----------------|---(S)-------|

网络 3(默认/备用):

|   iMode <> 1 AND iMode <> 2   |   bManual   |   bAuto   |
|---[CMP<>]---[CMP<>]----------|---(R)-------|---(R)-----|

使用置位/复位线圈 ((S)/(R)) 而非普通线圈,可使赋值保持有效:在一个网络中设置的标志位会一直保持置位状态,直到在另一个网络中被显式清除,这与 IF/ELSIF 语义完全相同。

5、使用比较树重新实现 CASE 语句

CASE 没有直接的 LAD 形式,但它可以清晰地映射到一个由 CMP== 网络组成的链,每个标签对应一个网络。网络的数量等于不同标签的数量。

SCL 源代码:

CASE iCmd OF
   10: bOpen  := TRUE;  bClose := FALSE;
   20: bOpen  := FALSE; bClose := TRUE;
   30: bOpen  := FALSE; bClose := FALSE;
   ELSE bAlarm := TRUE;
END_CASE;

LAD 网络 1(命令 10):

|   iCmd == 10   |   bOpen  |   bClose |
|---[CMP==]------|---(S)----|---(R)----|

对值 20 和 30 重复上述步骤。ELSE 分支将变成一个由“以上皆非”驱动的网络。标签数量越多,跳转标签结构 (JMP/LBL) 就越紧凑,但越难追踪;建议在 15 个 case 以内使用扁平网络。

可维护性提示:当 CASE 包含超过 10 个 case 且每个 case 都执行实际工作(例如多次赋值、调用函数控制器)时,保留 SCL 块,并从轻量级的 LAD 包装器中调用它。不要让 LAD 处理本质上是表格形式的代码。

6、循环和迭代逻辑必须保留在 SCL 中

LAD 基于扫描:每个网络在每个 PLC 周期内只执行一次。它没有原生的“循环回到同一个网络 10 次”的结构。西门子的解决方法是:

  • 将 FOR/WHILE 块保留在 SCL 中,并放在其自身的 FB 内。
  • 使用单个调用框从 LAD 调用该 FB(实例数据库会自动创建)。
  • 将循环边界作为 VAR_INPUT 参数传递,而不是作为 VAR_IN_OUT 数组传递——指针密集型签名也无法在 LAD 中表示。

LAD 调用者网络:

|   bExecute   |  "FB_LoopCtrl".bExecute    |
|---||----------|---[CALL FB_LoopCtrl_DB]---|
|              |   ENO                       |
|--------------|---( )-----------------------|

7、处理复杂数据类型和指针

使用常量索引 a[3] 访问数组和结构体可以干净地转换。动态索引 a[iIdx] 需要使用 "Fi“eldRead”/“FieldWrite”指令(DB_ANY 变体)或 PEEK/POKE 对,这两种指令在 LAD 中都无法表示。实用模式:

  • 将索引访问封装在一个小型 SCL 函数调用 (FC) 中:FC_GetElement : INT with VAR_IN_OUT arr : ARRAY[*] OF INT。
  • 从 LAD 调用该函数调用,并将返回的标量传递给比较/线圈网络。

对于 AT 覆盖视图,最简洁的解决方案是在数据库中声明一个并行结构体,并在单行 SCL 辅助函数中使用 MOVE_BLK 或 MOVE 在它们之间进行赋值。

8、字符串和浮点数转换

LAD 可以通过调用框直接调用内置的字符串转换函数调用 (FC_Strg_TO_Real, FC_Real_TO_Strg),但您无法使用触点自行构建转换。如果原始 SCL 块连接字符串,则需要进行以下操作:逐字符地,您必须保留 SCL 中的逻辑,或者将其替换为小型 SCL FC 中的 IEC 标准 CONCAT 指令。

9、创建新的 LAD 模块并粘贴网络

在项目树中,右键单击“程序模块”→“添加新模块”→“功能模块”。将其命名为 FB_LAD_Equivalent,并选择语言 LAD。

将 SCL 模块中的接口(输入、输出、输入/输出、静态、温度)复制到新模块中。名称和数据类型必须完全匹配。

对于每个转换后的网络,手动重新创建它。从右侧调色板中拖动一个触点、一个比较框和一个线圈。通过符号选择器或绝对地址设置操作数。

如果您使用了置位/复位线圈,请在首次扫描时添加一个单次复位网络(来自 OB100 的“FirstScan”标签或初始化系统位),以便在第一个周期之前清除所有保持输出。

使用 Ctrl+B 编译。必须解决任何交叉引用警告;LAD 将不接受。一个没有明确功率流路径的线圈。

编译陷阱:在 V17 中编译的 SCL 模块可能对定时器/计数器参数存在隐式 BCD 转换,而 V18/V19 LAD 编译器会将这些转换标记为“类型不匹配”。打开 SCL 源代码,将 T#1s 替换为 TIME#1s,然后在移植接口之前重新编译。

10、验证 — 与 PLCSIM 验证等效性

只有当 LAD 模块对相同的输入产生与 SCL 模块相同的输出时,转换才会完成。以下步骤使用两个 S7-PLCSIM 实例,实例 A 上的 SCL 模块和实例 B 上的 LAD 模块,两者都由同一个激励表提供数据。

  • 构建测试框架。创建一个 OB,该 OB 依次调用这两个模块,将 SCL 输出复制到“SCL_actual”标签集中,将 LAD 输出复制到“LAD_actual”标签集中,所有这些都在同一个数据块上。
  • 构建一个监视表,其中包含模块接口中的每个输入。覆盖边界值:整数取值为 0、max-1 或 max;字符串取值为空字符串、单个字符或最大长度;数组取值为第一个/最后一个元素。
  • 使用 S7-PLCSIM Sequencer 工具记录激励信号,或使用 TIA Portal V18+ 中的 TRC 跟踪记录器记录两个标签集随时间的变化。
  • 运行序列。逐个比较标签集。任何不匹配都属于转换错误。向测试 OB 添加一个网络,如果任意一对标签不同,则触发“diff_alarm”位:
// SCL auto-compare snippet
FOR i := 1 TO 16 DO
   IF SCL_actual[i] <> LAD_actual[i] THEN
      diff_alarm := TRUE;
   END_IF;
END_FOR;
  • 为了达到 100% 的覆盖率,编写一个小型 SIMATIC Automation Tool 脚本,该脚本下载测试程序、运行序列并输出差异标志。目标是 100%。连续激励周期,且 diff_alarm = FALSE。
  • 在模块属性中记录等效性测试结果(TIA Portal 允许在每个 FB 上添加自由文本注释)。该注释将成为下一位工程师的变更记录的一部分。

11、常见转换陷阱及其避免方法

转换失败模式及缓解措施

陷阱 症状 转换
忘记在调用中传播 ENO 下游网络始终为 FALSE 将每个调用盒的 ENO 连接到下一级,或使用 ---(SAVE)--- 显式禁用
混合使用绝对寻址和符号寻址 “未找到符号”警告 在 LAD/FBD 编辑器选项中选择一种模式,并将其应用于整个项目
使用 VAR_TEMP 作为内存位 标签每个周期重置为 0 将存储移动到实例 DB 上的 VAR_STATIC
取反比较阶梯 IF NOT (a = b) 自动转换器丢弃反转 替换为真正的取反比较:[CMP<>]
定时器值隐式 BCD 到 INT 转换 导致运行时值偏差 10 倍 请使用 IEC Timer 模块(SFB3/SFB4/IE_Timer)代替旧式 ---(SD)---
浮点 NaN 传播 所有比较均返回 FALSE 请在模块开头添加 IS_VALID_REAL 检查
求值顺序的细微差异 SCL a OR b OR c 在 SCL 中短路,而 LAD 会计算所有分支 为子表达式添加显式内存位;并通过边界情况验证等效性

12、何时不进行转换:边界情况

有时,正确的工程决策是保留 SCL 模块。仅当以下一个或多个条件为真时才进行转换:

  • 模块很小(<200 行),并且仅包含布尔/字逻辑。
  • 站点标准要求一线维护技术人员使用 LAD。
  • 下游代码路径正在迁移到不同的平台(例如,S7)。将 SCL 代码块转换为第三方 PLC 的 -1500 版本,实际上相当于重新实现,而非简单的转换。

当逻辑中使用带有多个标签的 CASE 语句、递归数据结构(数组中的链表)、状态数超过 20 的状态机或数值代码(缩放、插值、滤波运算)时,请保留 SCL 代码块。LAD 会使这些代码几乎无法阅读;而 SCL 则能将它们集中在一处。

13、文档检查清单

  • 新 LAD 代码块的块头注释:原始 SCL 源文件、转换日期、转换工具/方法、等效性测试参考。
  • 交叉引用:在原始 SCL 代码块的块头中添加指向新 LAD 代码块的“另请参阅”指针。
  • 版本控制:提交 SCL 源文件和新 LAD 源文件。切勿仅提交已编译的代码块,因为 LAD 生成器需要源文件才能重新显示。
  • 操作员 HMI:如果任何 HMI 标签指向原始代码块的静态变量,请更新 PLC 标签表。实例数据库名称已更改(从 FB_SCL_DB 更改为 FB_LAD_DB),因此符号引用失效。

‌             ‌

原文链接:Converting SCL to Ladder Diagram in TIA Portal Practical

汇智网翻译整理,转载请标明出处