博途 SCL 转梯形图实用指南
本指南记录了实际的工程路径:(1) TIA Portal 可以自动转换的内容;(2) 必须手动转换的模式;(3) 应该使用纯 LAD 重新实现而不是强制实现的模式;以及 (4) 验证新代码功能等效性的步骤。
梯形图转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
汇智网翻译整理,转载请标明出处