IEC61131-3 ST语言进阶 - 数组与字符串操作指南
ST/PLC
IEC61131-3 ST 语言进阶 - 数组与字符串操作指南
1. 数组操作
1.1 数组声明
VAR
// 一维数组
Data_Array : ARRAY[0..9] OF INT;
Sensor_Values : ARRAY[1..10] OF REAL;
// 多维数组
Matrix : ARRAY[0..2, 0..2] OF REAL;
Data_3D : ARRAY[0..9, 0..9, 0..9] OF BYTE;
// 带初始值
Defaults : ARRAY[0..4] OF INT := [10, 20, 30, 40, 50];
// 字符串数组
Messages : ARRAY[0..2] OF STRING[50] := [
'System Starting',
'System Running',
'System Stopped'
];
END_VAR
1.2 数组访问与操作
// 基本访问
Data_Array[0] := 100;
Value := Data_Array[i];
// 多维数组
Matrix[1, 2] := 3.14;
Matrix[i, j] := Value;
// 获取数组边界
Lower := LOWER_BOUND(Data_Array, 1); // 返回 0
Upper := UPPER_BOUND(Data_Array, 1); // 返回 9
// 数组赋值
FOR i := 0 TO 9 DO
Target_Array[i] := Source_Array[i];
END_FOR;
// 数组整体赋值(部分平台支持)
Target_Array := Source_Array;
1.3 实战:求平均值
FUNCTION FC_Average : REAL
VAR_INPUT
Data : ARRAY[0..9] OF REAL;
Count : INT;
END_VAR
VAR
i : INT;
Sum : REAL;
END_VAR
Sum := 0.0;
FOR i := 0 TO Count - 1 DO
Sum := Sum + Data[i];
END_FOR;
IF Count > 0 THEN
FC_Average := Sum / INT_TO_REAL(Count);
ELSE
FC_Average := 0.0;
END_IF;
END_FUNCTION
1.4 实战:查找最大值
FUNCTION FC_FindMax : INT
VAR_INPUT
Data : ARRAY[0..99] OF INT;
Size : INT;
END_VAR
VAR
i : INT;
MaxVal : INT;
END_VAR
MaxVal := Data[0];
FOR i := 1 TO Size - 1 DO
IF Data[i] > MaxVal THEN
MaxVal := Data[i];
END_IF;
END_FOR;
FC_FindMax := MaxVal;
END_FUNCTION
1.5 实战:冒泡排序
FUNCTION_BLOCK FB_Sort
VAR_IN_OUT
Data : ARRAY[0..99] OF INT;
END_VAR
VAR_INPUT
Size : INT;
END_VAR
VAR
i, j, Temp : INT;
Swapped : BOOL;
END_VAR
FOR i := 0 TO Size - 2 DO
Swapped := FALSE;
FOR j := 0 TO Size - 2 - i DO
IF Data[j] > Data[j + 1] THEN
Temp := Data[j];
Data[j] := Data[j + 1];
Data[j + 1] := Temp;
Swapped := TRUE;
END_IF;
END_FOR;
IF NOT Swapped THEN
EXIT; // 已排序完成,提前退出
END_IF;
END_FOR;
END_FUNCTION_BLOCK
2. 字符串操作
2.1 字符串基础
VAR
// 定长字符串
Name : STRING[80];
ShortStr : STRING[20] := 'Hello World';
// 宽字符串(Unicode,部分平台支持)
WideStr : WSTRING[50];
// 字符
CharVal : CHAR := 'A';
END_VAR
// 字符串赋值
Message := 'System Initialized';
2.2 字符串函数速查表
| 函数 | 说明 | 示例 | 结果 |
|---|---|---|---|
LEN() | 长度 | LEN('Hello') | 5 |
CONCAT() | 连接 | CONCAT('A','B') | ’AB’ |
LEFT() | 左截取 | LEFT('Hello',2) | ’He’ |
RIGHT() | 右截取 | RIGHT('Hello',2) | ’lo’ |
MID() | 中间截取 | MID('Hello',2,3) | ’ell’ |
FIND() | 查找位置 | FIND('Hello','ll') | 3 |
INSERT() | 插入 | INSERT('Hi',' World',2) | ’Hi World’ |
DELETE() | 删除 | DELETE('Hello',4,2) | ’Hell’ |
REPLACE() | 替换 | REPLACE('Hi','i','ello') | ’Hello’ |
UPPER() | 转大写 | UPPER('hello') | ’HELLO’ |
LOWER() | 转小写 | LOWER('WORLD') | ’world’ |
2.3 字符串连接
// 使用 CONCAT 函数
Result := CONCAT('Hello ', 'World'); // 'Hello World'
// 使用 + 运算符(部分平台支持)
Result := 'Hello ' + 'World'; // 'Hello World'
// 多段连接
FullMsg := CONCAT('Error: ', CONCAT('Code ', INT_TO_STRING(Code)));
2.4 字符串截取
Message := 'Temperature: 85.5';
// 提取数值部分
NumPart := MID(Message, 14, 4); // '85.5'
TempValue := STRING_TO_REAL(NumPart); // 85.5
// 截取前缀
Label := LEFT(Message, 13); // 'Temperature: '
// 截取后缀
Unit := RIGHT(Message, 2); // '5' (实际可能包含单位)
2.5 字符串查找与替换
Text := 'Sensor1 reading: 42.5';
// 查找子串位置
Pos := FIND(Text, 'reading'); // 返回 10(从0开始)
IF Pos >= 0 THEN
Found := TRUE;
END_IF;
// 替换
NewText := REPLACE(Text, 'Sensor1', 'Sensor2');
// 'Sensor2 reading: 42.5'
// 插入
Inserted := INSERT(Text, ' [OK]', 22);
// 'Sensor1 reading: 42.5 [OK]'
2.6 字符串与数值转换
// 字符串转数值
Value := STRING_TO_INT('1234'); // 1234
RealVal := STRING_TO_REAL('3.14'); // 3.14
// 数值转字符串
Str := INT_TO_STRING(1234); // '1234'
Str := REAL_TO_STRING(3.14); // '3.140000'
// 格式化拼接
Message := CONCAT('Temp: ', REAL_TO_STRING(Temp));
Message := CONCAT(Message, '°C');
3. 实战综合示例
3.1 数据过滤与统计
FUNCTION FC_FilterData : INT
VAR_INPUT
Data : ARRAY[0..99] OF REAL;
Size : INT;
MinVal : REAL;
MaxVal : REAL;
END_VAR
VAR
i : INT;
Count : INT;
END_VAR
Count := 0;
FOR i := 0 TO Size - 1 DO
IF Data[i] >= MinVal AND Data[i] <= MaxVal THEN
Count := Count + 1;
END_IF;
END_FOR;
FC_FilterData := Count;
END_FUNCTION
3.2 字符串解析(处理传感器数据)
FUNCTION_BLOCK FB_ParseSensorData
VAR_INPUT
RawString : STRING[100];
Delimiter : CHAR := ',';
END_VAR
VAR_OUTPUT
CH1 : REAL;
CH2 : REAL;
CH3 : REAL;
ParseOK : BOOL;
END_VAR
VAR
Pos1, Pos2, Pos3 : INT;
SubStr : STRING[50];
END_VAR
// 查找分隔符位置
Pos1 := FIND(RawString, Delimiter);
IF Pos1 < 0 THEN
ParseOK := FALSE;
RETURN;
END_IF;
// 提取第一个值
SubStr := LEFT(RawString, Pos1);
CH1 := STRING_TO_REAL(SubStr);
// 提取第二个值
Pos2 := FIND(RawString, Delimiter); // 简化处理
IF Pos2 < 0 THEN
ParseOK := FALSE;
RETURN;
END_IF;
ParseOK := TRUE;
END_FUNCTION_BLOCK
文档版本:1.0 | 更新日期:2026-04-28 | 作者:JianLin Studio