跳到正文
Learn-LAD
示例库/SCL 训练:存储功能块

SCL 训练:存储功能块

OB 先做数据运算,再调用 SCL 功能块 Storage_System 管理 100 个货位(放入/取出/清空);演示 LAD + SCL + 全局/实例 DB。

进阶 多块 S7-1200 SCL FB DB 多块

导入到我的 TIA 项目

通过 TiaLink 把本示例的 6 个对象导入你当前打开的 TIA Portal 项目。导入前会先预检,默认不覆盖同名对象,导入后不会自动保存。

TiaLink 设置

默认 http://localhost:8080。也可以在本页地址后加 ?tialink= 临时指定。

TiaLink 启动时若设置了 --api-token,这里要填相同的值;只保存在本机浏览器 localStorage,不会上传。

概述

这个示例由两种语言、三个块组成:Main(OB)先在 SCL 网络里做数据运算,再用 LAD 调用 SCL 功能块 Storage_System;功能块管理 100 个货位的放入、取出和清空。

它是多块工程的典型结构:主程序负责调度,功能块负责具体业务,数据放在全局 DB / 实例 DB 里。讲解按块分开,先看主程序,再看功能块。

信号表

对象 类型 含义 作用
Data.Number_01_int Int 运算结果 主程序 SCL 的写入目标
Data.Number_02_int / _03_int Int 整数输入 参与加法/乘法
Data.Number_04_real / _05_real / _06_real Real 浮点数据 参与减法和除法
Storage.Selected_Shelf Int 选中货位号 0~99
Storage.Put_In Bool 放入命令 置位对应货位
Storage.Take_Out Bool 取出命令 复位对应货位
Storage.Empty_Storage Bool 清空命令 复位全部货位
Storage.Shelfs Bool 数组 100 个货位状态 FB 内部按索引读写
Storage_System_DB 实例 DB Storage_System 的实例数据 保存 FB 的静态变量

点表 Default tag table 是空的;这个示例的数据都在 DB 里,不在 I/O 点表。

工作流程

  1. 每个扫描周期先执行 Main 的 Network 1(SCL 数据运算);
  2. 再执行 Network 2,用 LAD 调用 Storage_System,把 Storage 的命令和货位数组传进去;
  3. Storage_System 根据 Put_In/Take_Out/Empty_Storage 修改 Shelfs;
  4. Put_In 与 Take_Out 同时为 1 时置位 #Error;Empty_Storage=1 时用 FOR 循环清空 0~99 号货位。

MainOB · 主程序

Network 1 — 数据运算(SCL)

SCL
1"Data".Number_01_int := ("Data".Number_02_int + "Data".Number_03_int) * 3;2"Data".Number_06_real := INT_TO_REAL("Data".Number_03_intRet_Val) / 7;3"Data".Number_04_real -= "Data".Number_05_real;

目的:在 OB 里直接写 SCL,做整数和浮点运算。

条件 → 动作:Number_01_int = (Number_02_int + Number_03_int) * 3;Number_06_real = INT_TO_REAL(...) / 7;Number_04_real -= Number_05_real。

为什么:OB 里可以混用 LAD 和 SCL 网络;简单的算术用 SCL 表达比梯形图更直观。

注意:代码里的 "Data".Number_03_intRet_Val 看起来像原工程的笔误(多了 Ret_Val 后缀),实际字段应以 DB 定义为准;Number_04_real -= 是 SCL 的复合赋值写法。

Network 2 — 调用货位管理 FB(LAD)

Network 2

目的:把 DB 里的命令和货位数组传给 Storage_System。

条件 → 动作:调用 Storage_System,参数映射为 Selected_Shelf、Put_In、Empty_Storage、Take_Out、Shelfs;实例使用 Storage_System_DB。

为什么:LAD 的调用框把输入/输出参数列得很清楚,比在 SCL 里手写调用更适合展示接口。

注意:调用是每个扫描周期都执行的(OB1 的常态),所以 FB 内部逻辑必须能处理"命令保持为 1"的情况。

Storage_SystemFB · 功能块(SCL)

名称数据类型注释
Input
Selected_ShelfInt
Put_InBool
Empty_StorageBool
Take_OutBool
Output
ErrorBool
InOut
ShelfsArray[0..99] of Bool
Static
Temp
XSInt
Constant

Network 1 — 放入 / 取出 / 清空(SCL)

SCL
1    // Take out & Put in Code2IF #Put_In AND #Take_Out = FALSE THEN3    // Statement section IF4    #Shelfs[#Selected_Shelf] := TRUE;5    6ELSIF #Take_Out AND #Put_In = FALSE THEN7    // Statement section IF8    #Shelfs[#Selected_Shelf] := FALSE;9    10ELSIF #Put_In AND #Take_Out THEN11    // Statement section IF12    #Error := TRUE;13    14END_IF;151617// RESET All18IF #Empty_Storage = TRUE THEN19    FOR #X := 0 TO 99 DO20        // Statement section FOR21        #Shelfs[#X] := FALSE;22    END_FOR;23END_IF;24

目的:管理 100 个货位的状态。

条件 → 动作:

  • Put_In=1 且 Take_Out=0 → Shelfs[Selected_Shelf] := TRUE;
  • Take_Out=1 且 Put_In=0 → Shelfs[Selected_Shelf] := FALSE;
  • 两者同时为 1 → Error := TRUE;
  • Empty_Storage=1 → FOR 循环把 Shelfs[0..99] 全部置 FALSE。

为什么:用 IF/ELSIF 处理互斥命令,用 FOR 循环批量清空;数组下标直接来自 Selected_Shelf。

注意:代码里 #Error 只置位、没有复位;Selected_Shelf 超出 0~99 会造成数组越界(SCL 可能报错或写错位置)。

常见问题

  • 功能块不动作:确认 Storage_System_DB 已作为实例 DB 存在,调用参数映射正确。
  • 货位号越界:Selected_Shelf 必须限制在 0~99;可在 FB 里加范围检查。
  • Error 一直为 1:当前逻辑没有复位 #Error,需要增加复位条件。
  • SCL 代码编译不过:注意原工程里的 Number_03_intRet_Val 和数组类型定义,按实际 DB 字段修正。

变体与扩展

  • 加范围保护:在 IF 前检查 Selected_Shelf 是否在 0~99 内。
  • 加错误复位:用 Reset 参数清除 #Error。
  • 多货架:把 Shelfs 扩展成二维数组,按区域 + 货位管理。

变量与数据块

变量表:Default tag table

名称数据类型地址注释
(空变量表)
Data 全局 DB
名称数据类型起始值注释
Static
Number_01_intInt
Number_02_intInt
Number_03_intInt
Number_04_realReal
Number_05_realReal
Number_06_realReal
Storage 全局 DB
名称数据类型起始值注释
Static
Put_InBool
Take_OutBool
Selected_ShelfInt
Empty_StorageBool
ShelfArray[0..99] of Bool
Storage_System_DB 实例 DB(Storage_System)
名称数据类型起始值注释
Input
Selected_ShelfInt
Put_InBool
Empty_StorageBool
Take_OutBool
Output
ErrorBool
InOut
ShelfsArray[0..99] of Bool
Static

下一步