关于 scl-syntax
面向 Siemens TIA Portal V20+ PLC 程序员的 SCL 语法技能,提供语法规则、代码模式和参考资料。重点包括命名参数、持久变量声明,以及 FC 与 FB 的选择。
主要功能
- 01说明 SCL 关键语法规则
- 02指导 FC、FB 与 DB 的选择
- 03提供函数与数据类型参考
- 04汇总反模式和校验清单
- 05提供标准代码块模板
适用场景
- 01编写 Siemens PLC 的 SCL 程序
- 02为有状态逻辑选择 FB
- 03检查定时器和函数参数写法
- 04查找原生函数用法与示例
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ deluale/ framework_parser --skill scl-syntax安装后在 Claude Code 中输入/scl-syntax确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
anti-patterns.mdcore-functions.mddata-types.mdREFACTORING_SUMMARY.md详细介绍
SCL 语法技能
为 Siemens TIA Portal V20+ PLC 编程提供 SCL 语法帮助。 为 Siemens TIA Portal V20+ PLC 编程提供 SCL 语法帮助。
🚨 不可妥协的关键规则
R1:始终使用命名参数
IT:所有原生函数参数都必须使用命名参数语法:输入使用 :=,输出使用 =>。
EN:All native function parameters MUST use named parameter syntax with := for inputs and => for outputs.
// ✅ CORRETTO / CORRECT
result := LIMIT(MN := 0, IN := value, MX := 100);
#Motor1(Start := signal, Running => output);
// ❌ SBAGLIATO / WRONG - ERRORE COMPILAZIONE!
result := LIMIT(0, value, 100);
#Motor1(signal, output);
R2:Timer/Counter/Trigger 使用持久存储
IT:Timer、Counter、Trigger 必须在 VAR(FB)或 VAR_STAT 中声明,绝不能在 VAR_TEMP 中声明。VAR_TEMP 会在每个 PLC 周期重置!
EN:Timer, Counter, Trigger MUST be declared in VAR (FB) or VAR_STAT, NEVER in VAR_TEMP. VAR_TEMP resets every PLC cycle!
// ❌ SBAGLIATO / WRONG
VAR_TEMP
myTimer : TON; // ERRORE: timer si resetta ogni ciclo!
END_VAR
// ✅ CORRETTO / CORRECT
VAR
myTimer : TON; // OK: memoria persistente tra cicli
END_VAR
R3:使用 ELSIF,不要使用 ELSEIF
IT:在 SCL 中使用 ELSIF,而不是其他语言中的 ELSEIF。
EN:In SCL use ELSIF, not ELSEIF.
// ✅ CORRETTO / CORRECT
IF temp < 0 THEN
state := 'FROZEN';
ELSIF temp < 100 THEN // ELSIF!
state := 'LIQUID';
ELSE
state := 'GAS';
END_IF;
R4:赋值使用 :=,输出使用 =>
IT:调用 Function Block 时,输入使用 :=,输出使用 =>。
EN:Use := for inputs, => for outputs when calling Function Block.
// ✅ CORRETTO / CORRECT
#Motor1(
Start := startButton, // IN: usa :=
Speed := speedValue, // IN: usa :=
Running => motorStatus, // OUT: usa =>
Error => errorFlag // OUT: usa =>
);
R5:FC 与 FB/Function 与 Function Block
IT:
- FC (Function):用于无状态逻辑(计算、转换)
- FB (Function Block):用于具有持久内存的有状态逻辑(电机、阀门、顺序)
EN:
- FC (Function): For stateless logic (calculations, transformations)
- FB (Function Block): For stateful logic with persistent memory (motors, valves, sequences)
决策树:FC 与 FB
Hai bisogno di memoria persistente? / Need persistent memory?
├─ NO → Usa FC / Use FC
│ └─ Esempi: calcoli, conversioni, media, controlli
│ Examples: calculations, conversions, averaging, validations
│
└─ SI → Usa FB / Use FB
└─ Esempi: motori, timer, sequenze, state machine
Examples: motors, timers, sequences, state machines
3 步工作流
STEP 1:识别块类型 / Identify block type
- 无状态的循环逻辑 → FC (Function) / Stateless logic → FC
- 带记忆的控制(电机、阀门、顺序)→ FB (Function Block) / Stateful control → FB
- 全局数据 → DB (Data Block) 或 PLC Tags
STEP 2:查询原生函数 / Check native functions
- Core Functions:对于常用函数(LIMIT、MIN、MAX、TON、CONCAT 等),请查阅
scl-reference/core-functions.md - Extended Functions:对于另外 192 个函数,Claude 会自动读取
scl-reference/functions/中的 JSON 数据库 - Usage Examples:请参阅
scl-reference/USAGE_EXAMPLE.md查看实用示例
STEP 3:使用检查清单验证 / Validate with checklist
- 命名参数 ✓
- Timer 在 VAR 中(不在 VAR_TEMP 中)✓
- ELSIF(不是 ELSEIF)✓
- 请查阅
scl-reference/anti-patterns.md,了解需要避免的常见错误
📋 标准块模板
FC 模板(Function)
FUNCTION "Calculate_Average" : REAL
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
values : Array[0..9] of Real; // Array di valori
count : Int; // Numero elementi
END_VAR
VAR_TEMP
sum : Real; // Somma temporanea
i : Int; // Indice loop
END_VAR
BEGIN
// Validazione input / Input validation
IF count <= 0 OR count > 10 THEN
#Calculate_Average := 0.0;
RETURN;
END_IF;
// Calcolo media / Calculate average
sum := 0.0;
FOR i := 0 TO count - 1 DO
sum := sum + values[i];
END_FOR;
// Ritorna risultato / Return result
#Calculate_Average := sum / TO_REAL(count);
END_FUNCTION
FB 模板(Function Block - State Machine)
FUNCTION_BLOCK "Motor_Control"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
Start : Bool; // Segnale avvio
Stop : Bool; // Segnale stop
SpeedSetpoint : Real; // Velocità richiesta
END_VAR
VAR_OUTPUT
Running : Bool; // Motore in marcia
ActualSpeed : Real; // Velocità attuale
Alarm : Bool; // Flag allarme
END_VAR
VAR
State : Int; // 0=Idle, 1=Starting, 2=Running
StartTimer : TON; // Timer avvio (DEVE essere in VAR!)
ErrorCount : Int;
END_VAR
VAR_TEMP
tempSpeed : Real; // Variabile di lavoro temporanea
END_VAR
BEGIN
// State machine
CASE State OF
0: // Idle
IF Start AND NOT Stop THEN
State := 1;
#StartTimer(IN := FALSE, PT := T#0ms); // Reset timer
END_IF;
Running := FALSE;
1: // Starting
#StartTimer(IN := TRUE, PT := T#2s);
IF #StartTimer.Q THEN
State := 2;
Running := TRUE;
END_IF;
IF Stop THEN
State := 0;
END_IF;
2: // Running
Running := TRUE;
// Limita velocità tra 0 e 3000 RPM
ActualSpeed := LIMIT(
MN := 0.0,
IN := SpeedSetpoint,
MX := 3000.0
);
IF Stop THEN
State := 0;
Running := FALSE;
END_IF;
END_CASE;
// Gestione allarmi / Alarm handling
IF ActualSpeed > 3000.0 * 1.1 THEN
Alarm := TRUE;
ErrorCount := ErrorCount + 1;
END_IF;
END_FUNCTION_BLOCK
🔄 控制结构
IF-ELSIF-ELSE 条件语句
// Condizionale semplice / Simple conditional
IF temperature > 100.0 THEN
alarm := TRUE;
shutdownHeater();
END_IF;
// Condizionale completo / Full conditional
IF pressure < 1.0 THEN
status := 'LOW';
ELSIF pressure > 10.0 THEN
status := 'HIGH';
ELSE
status := 'NORMAL';
END_IF;
// Condizioni combinate / Combined conditions
IF (temp > 80.0) AND (pressure > 5.0) OR emergencyStop THEN
shutdown := TRUE;
END_IF;
CASE 语句(用于状态机)
// Ottimo per state machine e selezione multi-valore
CASE state OF
0: // Idle
Running := FALSE;
IF StartCommand THEN
state := 1;
END_IF;
1: // Starting
Running := TRUE;
IF startupComplete THEN
state := 2;
END_IF;
2: // Running
processControl();
IF StopCommand THEN
state := 3;
END_IF;
3: // Stopping
IF shutdownComplete THEN
state := 0;
END_IF;
ELSE
// Stato invalido - vai in error
state := 99;
errorFlag := TRUE;
END_CASE;
FOR 循环
// Loop con contatore crescente / Ascending counter loop
FOR i := 0 TO 9 DO
temperatures[i] := readSensor(i);
END_FOR;
// Loop con contatore decrescente / Descending counter loop
FOR i := 10 DOWNTO 0 DO
buffer[i] := 0;
END_FOR;
// Loop con incremento custom / Custom increment
FOR i := 0 TO 100 BY 5 DO
// i = 0, 5, 10, 15, ..., 100
processValue(i);
END_FOR;
// EXIT per uscita anticipata / Early exit
FOR i := 0 TO 99 DO
IF data[i] = targetValue THEN
foundIndex := i;
EXIT; // Esce dal loop
END_IF;
END_FOR;
// CONTINUE per saltare iterazione / Skip iteration
FOR i := 0 TO 99 DO
IF data[i] < 0 THEN
CONTINUE; // Salta al prossimo i
END_IF;
processPositiveValue(data[i]);
END_FOR;
WHILE 循环
// Pre-test (condizione prima esecuzione)
WHILE counter < 100 DO
counter := counter + 1;
process(counter);
END_WHILE;
// Con EXIT
WHILE TRUE DO
data := readData();
IF data = STOP_MARKER THEN
EXIT;
END_IF;
processData(data);
END_WHILE;
REPEAT 循环
// Post-test (esegue almeno una volta)
REPEAT
counter := counter + 1;
value := readSensor();
UNTIL (value > threshold) OR (counter >= maxRetries)
END_REPEAT;
// ⚠️ ATTENZIONE / WARNING: REPEAT termina quando condizione è TRUE
// (opposto di WHILE che continua quando TRUE)
📚 参考文件
何时查阅文件 / 何时查阅文件
对于常见的原生函数(LIMIT、MIN、MAX、TON、CONCAT 等):
→ 阅读 scl-reference/core-functions.md
- 包含最常用的 30 个函数及实用示例
- 完整签名、参数、用例
对于需要避免的常见错误:
→ 阅读 scl-reference/anti-patterns.md
- 包含 15+ 个反模式及解决方案的目录
- 性能和正确性错误
- 正确与错误的对比
对于数据类型(Int、Real、String、Array、Struct 等):
→ 阅读 scl-reference/data-types.md
- 基本类型和复杂类型的完整参考
- 类型转换
- 内存分配最佳实践
对于 Core 30 之外的函数:
→ Claude 会自动查询 scl-reference/functions/ 中的 JSON 数据库
- 按类别整理的 192 个附加函数
- Math、Comparison、Conversion、String、Move、Bitwise、Timers、Counters、Triggers
- 通过
index.json自动查找
对于实用示例:
→ 阅读 scl-reference/USAGE_EXAMPLE.md
- FC 和 FB 的完整示例
- 正确实现的常见模式
函数数据库 / 函数数据库
数据库结构:
scl-reference/functions/
├── index.json # Indice completo 222 funzioni
├── math.json # Funzioni matematiche avanzate
├── comparison.json # Comparazioni e selezioni
├── conversion.json # Conversioni di tipo
├── string.json # Manipolazione stringhe
├── move.json # Trasferimento dati
├── bitwise.json # Operazioni bitwise
├── timers.json # Timer avanzati
├── counters.json # Contatori
└── triggers.json # Trigger eventi
自动查找流程:
- Claude 阅读
index.json,确定函数类别 - 阅读该类别对应的 JSON 文件
- 提取包含参数和示例的完整定义
- 按照 Core Functions 的风格整理回答
✅ 提交前自检 / 验证清单
完成 SCL 代码前,检查以下所有项目:
- 命名参数:所有原生函数参数均使用
:=(IN)和=>(OUT) - 定时器存储:Timer/Counter/Trigger 位于
VAR(FB)或VAR_STAT中,绝不放在VAR_TEMP中 - ELSIF 语法:条件中使用
ELSIF(而不是ELSEIF) - 原生函数:已查阅 core-functions.md,未重新实现 LIMIT、MIN、MAX 等函数
- 边沿检测:使用 R_TRIG/F_TRIG(而不是手动检测边沿)
- 数组操作:使用 MOVE_BLK/FILL_BLK(而不是通过 FOR 循环进行复制/填充)
- 字符串操作:使用 CONCAT(而不是 + 运算符)
- 输入验证:检查输入范围和值是否有效
- 错误处理:适当处理报警/错误
- 命名:变量使用描述性名称(最终名称不使用
i、x、temp) - 注释:为复杂或不明显的逻辑添加注释
- 块类型:无状态逻辑使用 FC,有状态逻辑使用 FB
- 反模式:已检查 anti-patterns.md,避免常见错误
📝 快速参考 / 快速参考
SCL 关键字:
FUNCTION/FUNCTION_BLOCK- 定义块VAR/VAR_INPUT/VAR_OUTPUT/VAR_TEMP- 声明区段BEGIN/END_FUNCTION/END_FUNCTION_BLOCK- 分隔符IF/ELSIF/ELSE/END_IF- 条件语句CASE/OF/END_CASE- Switch 语句FOR/TO/DOWNTO/BY/END_FOR- 枚举循环WHILE/END_WHILE- 前测试循环REPEAT/UNTIL/END_REPEAT- 后测试循环EXIT/CONTINUE- 循环控制RETURN- 函数退出
运算符:
:=- 赋值 / 输入赋值=>- 输出参数 / 输出参数=- 比较 / 比较<>- 不等于 / 不同AND/OR/NOT- 逻辑运算符&/|/XOR- 按位运算符
技能版本 / 技能版本:2.0
目标:TIA Portal V20+ / S7-1500 / S7-1200
标准:IEC 61131-3 SCL
语言:双语(意大利语 + 英语)
架构:渐进式披露(核心内容位于 SKILL.md,详细内容位于 references/)