一、SCL 基础认知

SCL 是西门子 PLC 的结构化文本编程语言,语法类似 Pascal / 高级语言,支持变量声明、逻辑判断、循环、函数调用、数据块操作等,适合处理复杂的数学计算、流程控制、数据处理场景。核心特点:

  • 可读性强,适合复杂逻辑编写;
  • 支持结构化编程(FB/FC/DB/OB);
  • 兼容西门子全系列 PLC(S7-1200/1500/300/400)。

二、SCL 核心语法详解(附示例)

1. 变量声明(最基础也是最核心)

SCL 的变量声明必须遵循 “先声明,后使用” 原则,按作用域分为:输入变量、输出变量、输入输出变量、内部变量、临时变量。

通用声明格式:

VAR  // 普通内部变量(FB/FC/DB中,数据持久保存)
    变量名: 数据类型 := 初始值;
END_VAR

VAR_INPUT  // 输入变量(外部传入)
    变量名: 数据类型;
END_VAR

VAR_OUTPUT  // 输出变量(向外传递)
    变量名: 数据类型;
END_VAR

VAR_IN_OUT  // 输入输出变量(双向传递)
    变量名: 数据类型;
END_VAR

VAR_TEMP  // 临时变量(仅当前周期有效,执行完清空)
    变量名: 数据类型;
END_VAR

常用数据类型:

类型说明示例
BOOL布尔型(0/1)MotorRun: BOOL;
INT整数(-32768~32767)Count: INT := 0;
REAL浮点数(小数)Speed: REAL := 50.5;
STRING字符串Msg: STRING[20] := "Hello SCL";
ARRAY数组Data: ARRAY[1..10] OF INT;

示例(FB 中变量声明):

// FB1: 电机控制功能块
VAR_INPUT
    Start: BOOL;        // 启动信号(I0.0)
    Stop: BOOL;         // 停止信号(I0.1)
    SetSpeed: REAL;     // 设定速度(如50.0 r/min)
END_VAR

VAR_OUTPUT
    MotorRun: BOOL;     // 电机运行输出(Q0.0)
    ActualSpeed: REAL;  // 实际速度反馈
END_VAR

VAR
    RunFlag: BOOL := FALSE;  // 内部运行标志(初始值FALSE)
    SpeedArray: ARRAY[1..5] OF REAL;  // 速度缓存数组
END_VAR

VAR_TEMP
    TempValue: INT;  // 临时变量,仅当前周期有效
END_VAR
2. 基本运算与逻辑判断
(1)算术运算
运算符说明示例
+加法A := 10 + 5; // A=15
-减法B := 20 - 8; // B=12
*乘法C := 3 * 4; // C=12
/除法D := 10 / 2; // D=5
MOD取余E := 7 MOD 3; // E=1
(2)逻辑运算
运算符说明示例
AND逻辑与IF Start AND RunFlag THEN ...
OR逻辑或IF Alarm1 OR Alarm2 THEN ...
NOT逻辑非RunFlag := NOT Stop;
XOR逻辑异或Flag := A XOR B;
(3)条件判断(IF-THEN-ELSE)

最常用的流程控制语句,适合分支逻辑。示例(电机启停控制):

// 核心逻辑:停止优先
IF Stop THEN
    RunFlag := FALSE;  // 停止按钮按下,运行标志置FALSE
ELSIF Start THEN
    RunFlag := TRUE;   // 启动按钮按下,运行标志置TRUE
END_IF;

// 输出赋值
MotorRun := RunFlag;  // 运行标志同步到输出点

多分支示例(温度区间判断):

VAR
    Temp: REAL := 25.5;  // 检测温度
    TempLevel: INT;      // 温度等级
END_VAR

IF Temp < 0 THEN
    TempLevel := 1;  // 低温
ELSIF Temp >= 0 AND Temp < 30 THEN
    TempLevel := 2;  // 常温
ELSIF Temp >= 30 AND Temp < 50 THEN
    TempLevel := 3;  // 中温
ELSE
    TempLevel := 4;  // 高温
END_IF;
(4)CASE 语句(多值分支)

适合固定值的分支判断,比多层 IF 更简洁。示例(模式选择):

VAR
    Mode: INT := 2;  // 运行模式(1-手动,2-自动,3-调试)
    ModeMsg: STRING[20];
END_VAR

CASE Mode OF
    1: ModeMsg := "手动模式";
    2: ModeMsg := "自动模式";
    3: ModeMsg := "调试模式";
    ELSE: ModeMsg := "无效模式";  // 默认分支
END_CASE;
3. 循环语句

适合重复执行一段逻辑,常用FOR和WHILE循环。

(1)FOR 循环(固定次数循环)

语法:FOR 循环变量 := 起始值 TO 结束值 BY 步长 DO ... END_FOR;示例(数组赋值):

VAR
    DataArray: ARRAY[1..10] OF INT;  // 10个整数的数组
    i: INT;  // 循环变量
END_VAR

// 给数组赋值:DataArray[1]=1, DataArray[2]=2...DataArray[10]=10
FOR i := 1 TO 10 BY 1 DO
    DataArray[i] := i;
END_FOR;
(2)WHILE 循环(条件循环)

语法:WHILE 条件 DO ... END_WHILE;示例(计数到 100 停止):

VAR
    Count: INT := 0;
END_VAR

// 计数到100停止
WHILE Count < 100 DO
    Count := Count + 1;
    // 可添加其他逻辑,如数据采集、累加等
END_WHILE;
4. 数据块(DB)操作

SCL 中访问 DB 块数据的语法清晰,支持直接访问和符号访问。

(1)访问全局 DB

假设创建了全局 DB:DB1(名称:GlobalDB),包含变量:

VAR_GLOBAL
    LineSpeed: REAL := 50.0;  // 生产线速度
    ProductionCount: INT := 0;  // 产量计数
END_VAR

访问方式 1(符号访问,推荐):

// 产量计数+1
"GlobalDB".ProductionCount := "GlobalDB".ProductionCount + 1;
// 修改生产线速度
"GlobalDB".LineSpeed := 60.5;

访问方式 2(绝对地址访问):

// DB1.DBD0 对应LineSpeed(REAL占4字节)
DB1.DBD0 := 60.5;
// DB1.DBW4 对应ProductionCount(INT占2字节)
DB1.DBW4 := DB1.DBW4 + 1;
(2)访问 FB 背景 DB

调用 FB 时关联背景 DB 后,可直接访问背景 DB 中的变量:

// 调用FB1,关联背景DB:Motor1_DB
CALL "MotorControlFB", "Motor1_DB" (
    Start := I0.0,
    Stop := I0.1,
    MotorRun => Q0.0
);

// 访问背景DB中的内部变量RunFlag
"Motor1_DB".RunFlag := TRUE;
5. 函数 / 功能块调用
(1)调用 FC(功能)

假设创建 FC1:求和函数,声明如下:

// FC1: SumFC
VAR_INPUT
    A: INT;
    B: INT;
END_VAR
VAR_OUTPUT
    Sum: INT;
END_VAR

Sum := A + B;

SCL 调用方式:

VAR
    Result: INT;
END_VAR

// 调用FC1,传入参数10和20,结果存入Result
Result := "SumFC"(A := 10, B := 20);  // Result最终=30
(2)调用 FB(功能块)

以之前的电机控制 FB1 为例,SCL 调用语法:

// 方式1:直接调用
CALL "MotorControlFB", "Motor1_DB" (
    Start := I0.0,
    Stop := I0.1,
    SetSpeed := 50.0,
    MotorRun => Q0.0,
    ActualSpeed => MD20
);

// 方式2:先声明实例,再调用(适合多次访问)
VAR
    Motor1: "MotorControlFB" := "Motor1_DB";  // 声明FB实例
END_VAR

Motor1.Start := I0.0;
Motor1.Stop := I0.1;
Motor1();  // 执行FB逻辑
Q0.0 := Motor1.MotorRun;  // 赋值输出

三、完整实战示例(生产线计数 + 速度控制)

以下是一个完整的 SCL 程序示例,包含 OB1(主循环)、FC(计算)、FB(控制)、DB(数据存储),覆盖核心语法:

1. 全局 DB(GlobalDB,DB1)
VAR_GLOBAL
    ProductionCount: INT := 0;  // 总产量
    LineSpeed: REAL := 50.0;    // 设定速度
    LineRun: BOOL := FALSE;     // 生产线运行状态
END_VAR
2. FC(SpeedCalcFC,FC1):速度换算(r/min → m/s)
VAR_INPUT
    RpmSpeed: REAL;  // 转速(r/min)
    Radius: REAL;    // 滚轮半径(m)
END_VAR
VAR_OUTPUT
    MpsSpeed: REAL;  // 线速度(m/s)
END_VAR

// 公式:线速度 = 2 * π * 半径 * 转速 / 60
MpsSpeed := 2 * 3.14159 * Radius * RpmSpeed / 60;
3. FB(LineControlFB,FB1):生产线控制
VAR_INPUT
    StartLine: BOOL;  // 启动生产线(I0.0)
    StopLine: BOOL;   // 停止生产线(I0.1)
    Pulse: BOOL;      // 计数脉冲(I0.2,每触发一次产量+1)
END_VAR
VAR_OUTPUT
    LineRun: BOOL;    // 生产线运行输出(Q0.0)
    ActualMps: REAL;  // 实际线速度(MD30)
END_VAR
VAR
    RunFlag: BOOL := FALSE;
    PulseLast: BOOL := FALSE;  // 脉冲上一周期状态(防重复计数)
END_VAR

// 1. 生产线启停逻辑
IF StopLine THEN
    RunFlag := FALSE;
ELSIF StartLine THEN
    RunFlag := TRUE;
END_IF;
LineRun := RunFlag;

// 2. 产量计数(脉冲上升沿触发)
IF RunFlag THEN
    IF Pulse AND NOT PulseLast THEN
        "GlobalDB".ProductionCount := "GlobalDB".ProductionCount + 1;
    END_IF;
    PulseLast := Pulse;
END_IF;

// 3. 调用FC计算线速度
ActualMps := "SpeedCalcFC"(RpmSpeed := "GlobalDB".LineSpeed, Radius := 0.1);
4. OB1(主循环块)
// 调用生产线控制FB
CALL "LineControlFB", "LineControlDB" (
    StartLine := I0.0,
    StopLine := I0.1,
    Pulse := I0.2,
    LineRun => Q0.0,
    ActualMps => MD30
);

// 调试输出:产量超过1000时报警
IF "GlobalDB".ProductionCount > 1000 THEN
    Q0.1 := TRUE;  // Q0.1为报警输出
ELSE
    Q0.1 := FALSE;
END_IF;

四、SCL 编程注意事项

  1. 变量作用域:临时变量(VAR_TEMP)仅在当前扫描周期有效,不可用于保存状态;
  2. 数据类型匹配:运算时注意数据类型一致(如 REAL 和 INT 运算需先转换,用INT_TO_REAL等转换函数);
  3. 循环终止:WHILE 循环必须确保条件能终止,避免死循环导致 PLC 停机;
  4. 符号访问:优先使用符号名(如 "GlobalDB".LineSpeed)而非绝对地址,提高可读性和可维护性。

总结

  1. SCL 核心语法:变量声明(按作用域分类)、条件判断(IF/CASE)、循环(FOR/WHILE)、DB 访问、FB/FC 调用是基础,覆盖 80% 的编程场景;
  2. 数据块操作:全局 DB 用于共享数据,FB 背景 DB 用于保存状态,符号访问是推荐方式;
  3. 实战原则:复杂逻辑用 SCL(如计算、循环),简单逻辑可结合梯形图,FB/FC 封装复用逻辑,提升程序结构化程度。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐