博文

IEC61131-3 ST语言进阶 - 结构体、枚举与指针

ST/PLC

IEC61131-3 ST 语言进阶 - 结构体、枚举与指针

1. 结构体(STRUCT)

1.1 定义结构体

TYPE Motor_Params : STRUCT
    Speed : INT;              // 转速 RPM
    Torque : REAL;            // 扭矩 Nm
    Current : REAL;           // 电流 A
    Temperature : REAL;       // 温度 °C
    Running : BOOL;           // 运行状态
    Error_Code : INT;         // 错误码
    Last_Maintenance : DATE;  // 上次维护日期
    Name : STRING[20];        // 电机名称
END_STRUCT
END_TYPE

1.2 使用结构体

VAR
    Motor1 : Motor_Params;
    Motor2 : Motor_Params;
END_VAR

// 访问成员
Motor1.Speed := 1500;
Motor1.Torque := 45.5;
Motor1.Running := TRUE;
Motor1.Name := 'MainMotor';

// 整体赋值
Motor2 := Motor1;  // 所有成员复制

// 带初始化的声明
Motor3 : Motor_Params := (
    Speed := 0,
    Torque := 0.0,
    Running := FALSE,
    Name := 'SpareMotor'
);

1.3 嵌套结构体

TYPE Position : STRUCT
    X : REAL;
    Y : REAL;
    Z : REAL;
END_STRUCT
END_TYPE

TYPE Robot_State : STRUCT
    Pos : Position;
    Velocity : REAL;
    Mode : INT;
END_STRUCT
END_TYPE

VAR
    Robot : Robot_State;
END_VAR

// 访问嵌套成员
Robot.Pos.X := 100.0;
Robot.Pos.Y := 200.0;
Robot.Pos.Z := 50.0;

1.4 结构体数组

VAR
    Motor_Array : ARRAY[0..9] OF Motor_Params;
    i : INT;
END_VAR

// 批量初始化
FOR i := 0 TO 9 DO
    Motor_Array[i].Speed := 0;
    Motor_Array[i].Running := FALSE;
END_FOR;

// 访问
Motor_Array[3].Speed := 1500;

2. 枚举(ENUM)

2.1 定义枚举

TYPE Machine_State : (
    STATE_IDLE = 0,
    STATE_STARTING = 1,
    STATE_RUNNING = 2,
    STATE_STOPPING = 3,
    STATE_ERROR = 10,
    STATE_MAINTENANCE = 20
); END_TYPE

2.2 使用枚举

VAR
    CurrentState : Machine_State := Machine_State.STATE_IDLE;
END_VAR

CASE CurrentState OF
    Machine_State.STATE_IDLE:
        Initialize();
    Machine_State.STATE_RUNNING:
        Run_Process();
    Machine_State.STATE_ERROR:
        Handle_Error();
END_CASE;

2.3 枚举的优势

  • 📝 代码可读性强 - STATE_RUNNING2 更直观
  • 🔒 类型安全 - 不能赋无效值
  • 🛡️ 编译检查 - 漏写 CASE 分支时编译器可警告

2.4 实际枚举示例

TYPE Product_Type : (
    TYPE_A = 100,
    TYPE_B = 200,
    TYPE_C = 300
); END_TYPE

TYPE Error_Level : (
    INFO = 0,
    WARNING = 1,
    ERROR = 2,
    CRITICAL = 3
); END_TYPE

VAR
    CurrentProduct : Product_Type;
    LastError : Error_Level;
END_VAR

3. 联合体(UNION)

⚠️ 注意:部分 PLC 品牌不支持 UNION

3.1 定义与使用

TYPE Data_Packet : UNION
    As_Int : INT;
    As_Word : WORD;
    As_Bool_Array : ARRAY[0..15] OF BOOL;
END_UNION
END_TYPE

VAR
    Packet : Data_Packet;
    Word_Value : WORD;
    Bit_0 : BOOL;
END_VAR

Packet.As_Int := 12345;

// 通过不同视图访问同一数据
Word_Value := Packet.As_Word;
Bit_0 := Packet.As_Bool_Array[0];

3.2 实际应用场景

联合体常用于解析通信数据,同一字节流用不同方式解读。


4. 指针(POINTER)

4.1 指针基础

VAR
    Value : INT := 100;
    PtrValue : POINTER TO INT;
    ActualValue : INT;
END_VAR

// 获取地址
PtrValue := ADR(Value);

// 解引用
ActualValue := PtrValue^;  // ActualValue = 100

// 修改指针指向的值
PtrValue^ := 200;  // Value 现在等于 200

4.2 指针应用示例

// 动态数组访问
FUNCTION FC_GetElement : INT
VAR_INPUT
    BasePtr : POINTER TO INT;
    Index : INT;
END_VAR

FC_GetElement := (BasePtr + Index)^;

END_FUNCTION

// 数据交换
FUNCTION SWAP_Integers
VAR_IN_OUT
    A : POINTER TO INT;
    B : POINTER TO INT;
END_VAR
VAR
    Temp : INT;
END_VAR

Temp := A^;
A^ := B^;
B^ := Temp;

END_FUNCTION

4.3 指针与数组

VAR
    Data : ARRAY[0..99] OF INT;
    Ptr : POINTER TO INT;
    i : INT;
END_VAR

// 指向数组首地址
Ptr := ADR(Data[0]);

// 通过指针遍历
FOR i := 0 TO 99 DO
    Sum := Sum + (Ptr + i)^;
END_FOR;

5. REFERENCE TO(引用)

5.1 引用基础

VAR
    Original : INT := 50;
    Ref : REFERENCE TO INT;
END_VAR

Ref REF= Original;  // 建立引用

Ref := 100;  // Original 也变为 100

5.2 引用检查

IF IS_VALID_REF(Ref) THEN
    Value := Ref;
END_IF;

// 解除引用
Ref := REF(Original);  // 指向其他变量

6. 实战:设备数据结构

TYPE Device_Info : STRUCT
    ID : INT;
    Name : STRING[30];
    Type : INT;
    IP_Address : STRING[15];
    Online : BOOL;
END_STRUCT
END_TYPE

TYPE Sensor_Data : STRUCT
    Device : Device_Info;
    Value : REAL;
    Unit : STRING[10];
    Timestamp : TIME;
    Quality : INT;  // 0-100
END_STRUCT
END_TYPE

VAR
    Sensor1 : Sensor_Data;
    SensorArray : ARRAY[0..15] OF Sensor_Data;
END_VAR

// 使用
Sensor1.Device.ID := 1;
Sensor1.Device.Name := 'TempSensor_1';
Sensor1.Value := 85.5;
Sensor1.Unit := '°C';
Sensor1.Online := TRUE;

文档版本:1.0 | 更新日期:2026-04-28 | 作者:JianLin Studio

← 返回博文列表