IEC61131-3 ST语言实战 - 错误处理与通信指令
ST/PLC
IEC61131-3 ST 语言实战 - 错误处理与通信指令
1. 错误处理
1.1 手动错误检查(通用方法)
// 输入验证
FUNCTION FC_SafeDivide : REAL
VAR_INPUT
Numerator : REAL;
Denominator : REAL;
END_VAR
VAR_OUTPUT
Error : BOOL;
ErrorMsg : STRING[80];
END_VAR
IF Denominator = 0.0 THEN
Error := TRUE;
ErrorMsg := 'Error: Division by zero';
FC_SafeDivide := 0.0;
RETURN;
END_IF;
Error := FALSE;
FC_SafeDivide := Numerator / Denominator;
END_FUNCTION
1.2 错误码管理
// 定义错误枚举
TYPE ErrorCodes : (
ERR_NONE = 0,
ERR_OVERFLOW = 1,
ERR_UNDERFLOW = 2,
ERR_TIMEOUT = 3,
ERR_COMMUNICATION = 4,
ERR_INVALID_PARAM = 5
); END_TYPE
VAR
LastError : ErrorCodes := ErrorCodes.ERR_NONE;
END_VAR
// 检查并清除错误
IF LastError <> ErrorCodes.ERR_NONE THEN
Handle_Error(LastError);
LastError := ErrorCodes.ERR_NONE; // 清除错误
END_IF;
1.3 TRY-CATCH(部分平台支持)
TRY
// 可能出错的代码
Result := Value1 / Value2;
Parse_Result := STRING_TO_INT(InputStr);
CATCH
// 错误处理
Error_Flag := TRUE;
Error_Message := 'Division by zero or parse error';
END_TRY
// 带具体异常类型
TRY
Process_Data();
CATCH E_DIVISION_BY_ZERO
Handle_Zero_Division();
CATCH E_OUT_OF_RANGE
Handle_Range_Error();
CATCH
Handle_Generic_Error();
END_TRY
2. Modbus 通信
2.1 读保持寄存器
VAR
MB_Read : MB_READ_HOLDING;
Read_Data : ARRAY[0..9] OF WORD;
Read_Done : BOOL;
Read_Error : BOOL;
END_VAR
MB_Read(
ENABLE := TRUE,
MB_ADDR := 1, // 站号
START_ADDR := 100, // 起始地址
QUANTITY := 10, // 读取数量
DATA_PTR := Read_Data, // 数据存储地址
DONE => Read_Done,
ERROR => Read_Error
);
IF Read_Done THEN
// 处理读取的数据
Value1 := Read_Data[0];
Value2 := Read_Data[1];
END_IF;
2.2 写单个寄存器
VAR
MB_Write : MB_WRITE_SINGLE;
Write_Value : WORD;
Write_Done : BOOL;
END_VAR
MB_Write(
ENABLE := Write_Trigger,
MB_ADDR := 1,
START_ADDR := 200,
DATA_VALUE := Write_Value,
DONE => Write_Done,
ERROR => Write_Error
);
IF Write_Done THEN
Write_Trigger := FALSE; // 清除触发
END_IF;
2.3 Modbus 功能块封装
FUNCTION_BLOCK FB_ModbusManager
VAR_INPUT
Enable : BOOL;
ReadTrigger : BOOL;
WriteTrigger : BOOL;
WriteAddress : INT;
WriteValue : WORD;
END_VAR
VAR_OUTPUT
ReadData : ARRAY[0..15] OF WORD;
ReadDone : BOOL;
WriteDone : BOOL;
CommError : BOOL;
END_VAR
VAR
MB_Read : MB_READ_HOLDING;
MB_Write : MB_WRITE_SINGLE;
ReadState : INT := 0;
WriteState : INT := 0;
ErrorCounter : INT := 0;
END_VAR
IF NOT Enable THEN
ReadDone := FALSE;
WriteDone := FALSE;
RETURN;
END_IF;
// 读操作状态机
CASE ReadState OF
0: // 空闲
IF ReadTrigger THEN
ReadState := 1;
END_IF;
1: // 执行读取
MB_Read(
ENABLE := TRUE,
MB_ADDR := 1,
START_ADDR := 0,
QUANTITY := 16,
DATA_PTR := ReadData,
DONE => ReadDone,
ERROR => CommError
);
IF ReadDone OR CommError THEN
MB_Read.ENABLE := FALSE;
ReadState := 0;
IF CommError THEN
ErrorCounter := ErrorCounter + 1;
END_IF;
END_IF;
END_CASE;
// 写操作
IF WriteTrigger AND WriteState = 0 THEN
WriteState := 1;
END_IF;
IF WriteState = 1 THEN
MB_Write(
ENABLE := TRUE,
MB_ADDR := 1,
START_ADDR := WriteAddress,
DATA_VALUE := WriteValue,
DONE => WriteDone,
ERROR => CommError
);
IF WriteDone OR CommError THEN
MB_Write.ENABLE := FALSE;
WriteState := 0;
END_IF;
END_IF;
END_FUNCTION_BLOCK
3. 串行通信
3.1 发送数据
VAR
Serial_Send : SERIAL_SEND;
Send_Buffer : ARRAY[0..63] OF BYTE;
Send_Length : INT;
END_VAR
Serial_Send(
ENABLE := Send_Request,
DATA_PTR := Send_Buffer,
LENGTH := Send_Length,
DONE => Send_Complete,
ERROR => Send_Error
);
3.2 接收数据
VAR
Serial_Receive : SERIAL_RECEIVE;
Receive_Buffer : ARRAY[0..63] OF BYTE;
Receive_Length : INT;
END_VAR
Serial_Receive(
ENABLE := TRUE,
DATA_PTR := Receive_Buffer,
MAX_LENGTH := 64,
LENGTH => Receive_Length,
DONE => Receive_Complete
);
IF Receive_Complete THEN
// 处理接收到的数据
Process_Received_Data(Receive_Buffer, Receive_Length);
END_IF;
4. 通信超时处理
FUNCTION_BLOCK FB_CommWithTimeout
VAR_INPUT
Start : BOOL;
Timeout : TIME := T#5s;
END_VAR
VAR_OUTPUT
Done : BOOL;
TimeoutFlag : BOOL;
Error : BOOL;
END_VAR
VAR
Comm_Timer : TON;
Comm_Started : BOOL;
END_VAR
IF Start AND NOT Comm_Started THEN
Comm_Started := TRUE;
Comm_Timer(IN := TRUE, PT := Timeout);
Done := FALSE;
TimeoutFlag := FALSE;
Error := FALSE;
// 启动通信
Start_Communication();
END_IF;
// 检查超时
IF Comm_Started THEN
IF Comm_Timer.Q THEN
TimeoutFlag := TRUE;
Error := TRUE;
Comm_Started := FALSE;
END_IF;
// 通信完成
IF Comm_Done_Signal THEN
Done := TRUE;
Comm_Started := FALSE;
Comm_Timer(IN := FALSE);
END_IF;
END_IF;
END_FUNCTION_BLOCK
5. 实战:通信重试机制
FUNCTION_BLOCK FB_CommRetry
VAR_INPUT
Trigger : BOOL;
MaxRetries : INT := 3;
RetryDelay : TIME := T#1s;
END_VAR
VAR_OUTPUT
Success : BOOL;
Failed : BOOL;
RetryCount : INT;
END_VAR
VAR
RetryTimer : TON;
State : INT := 0;
Attempts : INT := 0;
END_VAR
CASE State OF
0: // 空闲
IF Trigger THEN
Attempts := 0;
Success := FALSE;
Failed := FALSE;
State := 1;
END_IF;
1: // 发起通信
Start_Communication();
State := 2;
2: // 等待结果
IF Comm_Success THEN
Success := TRUE;
State := 0;
ELSIF Comm_Error THEN
Attempts := Attempts + 1;
IF Attempts >= MaxRetries THEN
Failed := TRUE;
RetryCount := Attempts;
State := 0;
ELSE
RetryCount := Attempts;
RetryTimer(IN := TRUE, PT := RetryDelay);
State := 3;
END_IF;
END_IF;
3: // 延时重试
IF RetryTimer.Q THEN
RetryTimer(IN := FALSE);
State := 1;
END_IF;
END_CASE;
END_FUNCTION_BLOCK
文档版本:1.0 | 更新日期:2026-04-28 | 作者:JianLin Studio