跳到主要内容

系统函数与库

Darra PLC 运行时提供丰富的标准库函数,涵盖类型转换、数学运算、位操作、字符串处理、日期时间、边缘检测、定时器、计数器、通讯和诊断等类别。本文档按功能域分类列出各函数的签名、说明与使用示例。


1. 类型转换函数

类型转换函数遵循 源类型_TO_目标类型 命名约定,支持所有基本数据类型间的显式转换。

整数间转换

函数输入返回说明
BOOL_TO_BYTEBOOLBYTETRUE → 16#01, FALSE → 16#00
BOOL_TO_INTBOOLINTTRUE → 1, FALSE → 0
BOOL_TO_DINTBOOLDINTTRUE → 1, FALSE → 0
BYTE_TO_BOOLBYTEBOOL0 → FALSE, 非 0 → TRUE
BYTE_TO_INTBYTEINT无符号扩展
BYTE_TO_DINTBYTEDINT无符号扩展
INT_TO_BYTEINTBYTE截断低 8 位
INT_TO_DINTINTDINT符号扩展
INT_TO_WORDINTWORD位模式不变
DINT_TO_INTDINTINT截断低 16 位,超出范围截断
DINT_TO_BYTEDINTBYTE截断低 8 位
DINT_TO_WORDDINTWORD截断低 16 位
WORD_TO_DINTWORDDINT无符号扩展
WORD_TO_INTWORDINT位模式不变
VAR
bFlag : BOOL := TRUE;
byCode : BYTE;
iValue : INT;
diValue : DINT;
wWord : WORD;
END_VAR

byCode := BOOL_TO_BYTE(bFlag); // 16#01
iValue := BYTE_TO_INT(byCode); // 1
diValue := INT_TO_DINT(iValue); // 1
wWord := INT_TO_WORD(iValue); // 16#0001

浮点与整数间转换

函数输入返回说明
REAL_TO_INTREALINT舍入到最近整数,半入
REAL_TO_DINTREALDINT舍入到最近整数,半入
REAL_TO_STRINGREALSTRING格式化为十进制字符串
INT_TO_REALINTREAL整数转浮点
DINT_TO_REALDINTREAL双精度整数转浮点
STRING_TO_REALSTRINGREAL字符串解析为浮点值
STRING_TO_INTSTRINGINT字符串解析为整数
STRING_TO_DINTSTRINGDINT字符串解析为双精度整数

时间与日期转换

函数输入返回说明
TIME_TO_DINTTIMEDINT时间值转换为毫秒数
TIME_TO_REALTIMEREAL时间值转换为毫秒浮点数
DINT_TO_TIMEDINTTIME毫秒数转换为时间值
REAL_TO_TIMEREALTIME浮点毫秒数转换为时间值
DATE_TO_STRINGDATESTRING日期格式化为 YYYY-MM-DD
STRING_TO_DATESTRINGDATE解析 YYYY-MM-DD 格式字符串
TOD_TO_TIMETODTIME时刻转换为当日偏移时长
TIME_TO_TODTIMETOD时长转换为当日时刻
VAR
tDuration : TIME := T#2s500ms;
diMillis : DINT;
rMillis : REAL;
dToday : DATE := D#2026-04-07;
sDate : STRING[12];
todNow : TOD;
tOffset : TIME;
END_VAR

diMillis := TIME_TO_DINT(tDuration); // 2500
rMillis := TIME_TO_REAL(tDuration); // 2500.0
sDate := DATE_TO_STRING(dToday); // "2026-04-07"
tOffset := TOD_TO_TIME(todNow); // 当日偏移毫秒数

2. 数学函数

基础运算

VAR
rValue : REAL := -25.0;
rAbs : REAL;
rSqrt : REAL;
rLn : REAL;
rLog : REAL;
rExp : REAL;
rPower : REAL;
END_VAR

rAbs := ABS(rValue); // 25.0
rSqrt := SQRT(ABS(rValue)); // 5.0
rLn := LN(10.0); // 2.302585
rLog := LOG(100.0); // 2.0 (常用对数)
rExp := EXP(1.0); // 2.718282
rPower := EXPT(2.0, 8.0); // 256.0
函数输入返回说明
ABS(x)数值同输入绝对值
SQRT(x)REAL/LREALREAL/LREAL平方根,x ≥ 0
LN(x)REAL/LREALREAL/LREAL自然对数,x > 0
LOG(x)REAL/LREALREAL/LREAL常用对数(底 10),x > 0
EXP(x)REAL/LREALREAL/LREAL指数函数 e^x
EXPT(x, y)REAL, REALREAL幂运算 x^y

三角函数

VAR
rAngle : REAL := 1.5708; // π/2 弧度
rSin : REAL;
rCos : REAL;
rTan : REAL;
rAsin : REAL;
rAcos : REAL;
rAtan : REAL;
END_VAR

rSin := SIN(rAngle); // ≈ 1.0
rCos := COS(rAngle); // ≈ 0.0
rTan := TAN(0.7854); // ≈ 1.0
rAsin := ASIN(1.0); // 1.5708
rAcos := ACOS(0.0); // 1.5708
rAtan := ATAN(1.0); // 0.7854
函数输入返回说明
SIN(x)REAL/LREALREAL/LREAL正弦,x 为弧度
COS(x)REAL/LREALREAL/LREAL余弦,x 为弧度
TAN(x)REAL/LREALREAL/LREAL正切,x 为弧度
ASIN(x)REAL/LREALREAL/LREAL反正弦,x ∈ [-1, 1]
ACOS(x)REAL/LREALREAL/LREAL反余弦,x ∈ [-1, 1]
ATAN(x)REAL/LREALREAL/LREAL反正切

舍入与截断

VAR
rValue : REAL := 3.14159;
rTrunc : REAL;
rRound : REAL;
rCeil : REAL;
rFloor : REAL;
iTrunc : INT;
END_VAR

rTrunc := TRUNC(rValue); // 3.0
rRound := ROUND(rValue); // 3.0
rCeil := CEIL(rValue); // 4.0
rFloor := FLOOR(rValue); // 3.0
iTrunc := TRUNC(rValue); // 3 (返回 INT)
函数输入返回说明
TRUNC(x)REALREAL 或 INT截断小数部分(向零舍入)
ROUND(x)REALREAL四舍五入到最近整数
CEIL(x)REALREAL向上取整(向 +∞)
FLOOR(x)REALREAL向下取整(向 -∞)

选择与限幅

VAR
rA : REAL := 10.0;
rB : REAL := 20.0;
rC : REAL := 30.0;
rSel : REAL;
rMax : REAL;
rMin : REAL;
rLimit : REAL;
iMux : INT;
bCond : BOOL := TRUE;
END_VAR

rSel := SEL(bCond, rA, rB); // 10.0 (bCond=TRUE 返回 rA)
rMax := MAX(rA, rB, rC); // 30.0
rMin := MIN(rA, rB, rC); // 10.0
rLimit := LIMIT(rA, rC, rB); // 20.0 (值 30 被限幅在 [10, 20])
iMux := MUX(1, 100, 200, 300); // 200 (K=1 返回第 2 个参数)
函数参数返回说明
SEL(G, IN0, IN1)BOOL, T, TTG=TRUE 选 IN0,G=FALSE 选 IN1
MAX(IN0, IN1, ...)T, T, ...T返回最大值,支持 2+ 参数
MIN(IN0, IN1, ...)T, T, ...T返回最小值,支持 2+ 参数
LIMIT(MN, IN, MX)T, T, TT限幅:MN ≤ IN ≤ MX
MUX(K, IN0, IN1, ...)INT, T, T, ...T多路选择器,K 为通道索引

3. 位操作函数

移位操作

VAR
wValue : WORD := 16#00FF;
wShifted : WORD;
diValue : DINT := 16#000000FF;
diShifted : DINT;
wRotated : WORD;
END_VAR

wShifted := SHL(wValue, 4); // 16#0FF0 (左移 4 位)
wShifted := SHR(wValue, 4); // 16#000F (右移 4 位)
diShifted := SHL(diValue, 8); // 16#0000FF00
wRotated := ROL(wValue, 4); // 16#0FF0 (循环左移)
wRotated := ROR(wValue, 4); // 16#F00F (循环右移)
函数参数返回说明
SHL(IN, N)任意位类型, INT同输入逻辑左移 N 位,低位补 0
SHR(IN, N)任意位类型, INT同输入逻辑右移 N 位,高位补 0
ROL(IN, N)任意位类型, INT同输入循环左移 N 位
ROR(IN, N)任意位类型, INT同输入循环右移 N 位

位测试

位测试通过 SEL 与掩码组合实现,Darra 扩展支持直接位索引访问:

VAR
wStatus : WORD := 16#A5A5;
bBit7 : BOOL;
wMasked : WORD;
END_VAR

// 位测试
bBit7 := (wStatus AND 16#0080) <> 0; // 读 bit7

// 位置位/清零
wStatus := wStatus OR 16#0020; // 置位 bit5
wStatus := wStatus AND NOT 16#0020; // 清零 bit5

// 位翻转
wStatus := wStatus XOR 16#0001; // 翻转 bit0

// 位域提取
wMasked := SHR(wStatus, 4) AND 16#000F; // 提取 bit4-7

4. 字符串函数

IEC 61131-3 标准字符串函数,字符串索引从 1 开始计数。

VAR
sSource : STRING[64] := 'Darra PLC 系统';
sResult : STRING[64];
sPart : STRING[32];
iLen : INT;
iPos : INT;
END_VAR

iLen := LEN(sSource); // 14
sPart := LEFT(sSource, 5); // "Darra"
sPart := RIGHT(sSource, 3); // "系统"
sPart := MID(sSource, 3, 7); // "PLC" (从位置 7 取 3 字符)
sResult := CONCAT(sSource, ' v1.0'); // "Darra PLC 系统 v1.0"
iPos := FIND(sSource, 'PLC'); // 7
函数参数返回说明
LEN(STR)STRINGINT返回字符串实际长度(不含结尾空字符)
LEFT(STR, SIZE)STRING, INTSTRING取左侧 SIZE 个字符
RIGHT(STR, SIZE)STRING, INTSTRING取右侧 SIZE 个字符
MID(STR, SIZE, POS)STRING, INT, INTSTRING从 POS 取 SIZE 个字符
CONCAT(STR1, STR2)STRING, STRINGSTRING拼接两个字符串
FIND(STR1, STR2)STRING, STRINGINT返回 STR2 在 STR1 中的起始位置,未找到返回 0

字符串修改

VAR
sText : STRING[64] := 'Darra PLC 系统';
sResult : STRING[64];
END_VAR

sResult := INSERT(sText, '软件', 7); // "Darra 软件PLC 系统"
sResult := DELETE(sText, 6, 5); // "Darra 系统" (从位置 6 删 5 字符)
sResult := REPLACE(sText, 'Darra', '控制'); // "控制 PLC 系统"
函数参数返回说明
INSERT(STR1, STR2, POS)STRING, STRING, INTSTRING在 POS 位置插入 STR2
DELETE(STR, POS, LEN)STRING, INT, INTSTRING从 POS 开始删除 LEN 字符
REPLACE(STR1, STR2, LEN, POS)STRING, STRING, INT, INTSTRING从 POS 开始用 STR2 替换 LEN 字符

Darra 扩展字符串函数

VAR
sInput : STRING[64] := '温度,压力,流速';
sToken : STRING[32];
sReplace : STRING[64];
sTrim : STRING[64] := ' 带空格的字符串 ';
sUpper : STRING[64];
sLower : STRING[64];
sPad : STRING[64];
iCount : INT;
END_VAR

// 替换所有匹配项
sReplace := REPLACE_STR(sInput, ',', ' | '); // "温度 | 压力 | 流速"

// 去除首尾空白
sTrim := TRIM(sTrim); // "带空格的字符串"

// 大小写转换
sUpper := TO_UPPER(sInput); // "温度,压力,流速"
sLower := TO_LOWER(sInput); // "温度,压力,流速"

// 填充
sPad := LPAD('7', 4, '0'); // "0007"
sPad := RPAD('7', 4, '0'); // "7000"

// 统计子串出现次数
iCount := COUNT_STR(sInput, ','); // 2
Darra 扩展函数参数返回说明
REPLACE_STR(STR, OLD, NEW)STRING, STRING, STRINGSTRING替换所有匹配子串
TRIM(STR)STRINGSTRING去除首尾空白字符
TO_UPPER(STR)STRINGSTRING转换为大写(ASCII 部分)
TO_LOWER(STR)STRINGSTRING转换为小写(ASCII 部分)
LPAD(STR, LEN, CH)STRING, INT, STRINGSTRING左侧填充至指定长度
RPAD(STR, LEN, CH)STRING, INT, STRINGSTRING右侧填充至指定长度
COUNT_STR(STR, SUB)STRING, STRINGINT统计子串出现次数
字符串容量
  • STRING[N] 未指定 N 时默认 80 字符
  • 超出容量的赋值会被截断,不抛异常
  • 中文字符串建议用 WSTRING(UTF-16)避免编码问题
  • 高频周期中避免大量字符串拼接,拷贝开销显著

5. 日期时间函数

当前时间获取

VAR
dtNow : DT;
dToday : DATE;
todNow : TOD;
tElapsed : TIME;
sDate : STRING[12];
sTime : STRING[16];
sDt : STRING[24];
diMillis : DINT;
END_VAR

dtNow := GET_DATE_TIME(); // 当前日期时间 DT#2026-04-07-14:30:00
dToday := GET_DATE(); // 当前日期 D#2026-04-07
todNow := GET_TIME_OF_DAY(); // 当前时刻 TOD#14:30:00.123
tElapsed := GET_RUN_TIME(); // 系统运行时长
函数返回说明
GET_DATE_TIME()DT当前系统日期时间(64 位)
GET_DATE()DATE当前系统日期
GET_TIME_OF_DAY()TOD当前时刻(当日偏移)
GET_RUN_TIME()TIME系统运行时长(毫秒精度)

日期时间转换

VAR
dDate : DATE := D#2026-04-07;
sDate : STRING[12];
dParsed : DATE;
tOffset : TIME;
todTime : TOD;
wYear : WORD;
bMonth : BYTE;
bDay : BYTE;
wHour : WORD;
bMinute : BYTE;
bSecond : BYTE;
END_VAR

sDate := DATE_TO_STRING(dDate); // "2026-04-07"
dParsed := STRING_TO_DATE('2026-04-07'); // D#2026-04-07
tOffset := TOD_TO_TIME(TOD#14:30:00); // T#14h30m0s
todTime := TIME_TO_TOD(T#14h30m); // TOD#14:30:00

// 日期时间分解(Darra 扩展)
DECODE_DATE(dDate, wYear, bMonth, bDay); // 2026, 4, 7
DECODE_TIME(TOD#14:30:00.500, wHour, bMinute, bSecond, wMillisec); // 14, 30, 0, 500
函数参数返回说明
DATE_TO_STRING(DATE)DATESTRING格式化为 YYYY-MM-DD
STRING_TO_DATE(STR)STRINGDATE解析 YYYY-MM-DD 格式
TOD_TO_TIME(TOD)TODTIME时刻转换为当日偏移时长
TIME_TO_TOD(TIME)TIMETOD时长转换为当日时刻
DECODE_DATE(DATE)DATE将日期分解为年、月、日(Darra 扩展)
DECODE_TIME(TOD)TOD将时刻分解为时、分、秒、毫秒(Darra 扩展)

6. 边缘检测

边缘检测通过标准功能块 R_TRIG(上升沿)和 F_TRIG(下降沿)实现。

R_TRIG — 上升沿检测

FUNCTION_BLOCK R_TRIG
VAR_INPUT
CLK : BOOL; // 时钟输入
END_VAR
VAR_OUTPUT
Q : BOOL; // 上升沿脉冲输出
END_VAR
VAR
M : BOOL; // 内部状态记忆
END_VAR
Q := CLK AND NOT M;
M := CLK;
END_FUNCTION_BLOCK

F_TRIG — 下降沿检测

FUNCTION_BLOCK F_TRIG
VAR_INPUT
CLK : BOOL; // 时钟输入
END_VAR
VAR_OUTPUT
Q : BOOL; // 下降沿脉冲输出
END_VAR
VAR
M : BOOL; // 内部状态记忆
END_VAR
Q := NOT CLK AND M;
M := CLK;
END_FUNCTION_BLOCK

使用示例

VAR
rtStart : R_TRIG;
ftStop : F_TRIG;
bStartBtn : BOOL;
bStopBtn : BOOL;
bStartPulse : BOOL;
bStopPulse : BOOL;
bRun : BOOL;
END_VAR

// 上升沿检测
rtStart(CLK := bStartBtn);
bStartPulse := rtStart.Q;

// 下降沿检测
ftStop(CLK := bStopBtn);
bStopPulse := ftStop.Q;

// 应用:单按钮启停(上升沿切换)
IF bStartPulse THEN
bRun := NOT bRun;
END_IF;
功能块输入输出说明
R_TRIGCLK: BOOLQ: BOOLCLK 从 FALSE→TRUE 时 Q 输出一个扫描周期脉冲
F_TRIGCLK: BOOLQ: BOOLCLK 从 TRUE→FALSE 时 Q 输出一个扫描周期脉冲

7. 定时器函数

标准 IEC 61131-3 定时器功能块,支持 TON、TOF、TP 和 TONR(Darra 扩展)。

TON — 接通延时

VAR
tonDelay : TON;
bTrigger : BOOL;
bElapsed : BOOL;
tElapsed : TIME;
END_VAR

tonDelay(IN := bTrigger, PT := T#5s);
bElapsed := tonDelay.Q;
tElapsed := tonDelay.ET; // 当前计时值

TOF — 关断延时

VAR
tofDelay : TOF;
bTrigger : BOOL;
bElapsed : BOOL;
END_VAR

tofDelay(IN := bTrigger, PT := T#3s);
bElapsed := tofDelay.Q;

TP — 脉冲定时

VAR
tpPulse : TP;
bTrigger : BOOL;
bPulse : BOOL;
END_VAR

tpPulse(IN := bTrigger, PT := T#500ms);
bPulse := tpPulse.Q; // 输出固定宽度 500ms 脉冲

TONR — 累计接通延时(Darra 扩展)

VAR
tonrAccum : TONR;
bTrigger : BOOL;
bReset : BOOL;
bElapsed : BOOL;
tAccum : TIME;
END_VAR

tonrAccum(IN := bTrigger, R := bReset, PT := T#1h);
bElapsed := tonrAccum.Q;
tAccum := tonrAccum.ET; // 累计计时值,R=TRUE 时清零
功能块输入输出说明
TONIN: BOOL, PT: TIMEQ: BOOL, ET: TIMEIN=TRUE 开始计时,计时到 PT 后 Q=TRUE
TOFIN: BOOL, PT: TIMEQ: BOOL, ET: TIMEIN=FALSE 开始计时,计时到 PT 后 Q=FALSE
TPIN: BOOL, PT: TIMEQ: BOOL, ET: TIMEIN 上升沿输出固定宽度脉冲
TONRIN: BOOL, R: BOOL, PT: TIMEQ: BOOL, ET: TIME累计计时,R 复位,Darra 扩展
// 实际应用:电机超时保护
VAR
tonMotorGuard : TON;
bMotorOn : BOOL;
bMotorReady : BOOL;
bFault : BOOL;
END_VAR

tonMotorGuard(IN := bMotorOn, PT := T#10s);

// 电机启动后 10 秒内未就绪则报故障
IF tonMotorGuard.Q AND NOT bMotorReady THEN
bFault := TRUE;
END_IF;

8. 计数器函数

CTU — 加计数器

VAR
ctuCount : CTU;
bCountUp : BOOL;
bReset : BOOL;
bDone : BOOL;
iCount : INT;
END_VAR

ctuCount(CU := bCountUp, R := bReset, PV := 100);
bDone := ctuCount.Q; // 计数值 ≥ PV 时 Q=TRUE
iCount := ctuCount.CV; // 当前计数值

CTD — 减计数器

VAR
ctdCount : CTD;
bCountDown : BOOL;
bLoad : BOOL;
bDone : BOOL;
iCount : INT;
END_VAR

ctdCount(CD := bCountDown, LD := bLoad, PV := 50);
bDone := ctdCount.Q; // 计数值 ≤ 0 时 Q=TRUE
iCount := ctdCount.CV;

CTUD — 加减计数器(IEC 标准)

VAR
ctudCount : CTUD;
bCountUp : BOOL;
bCountDown : BOOL;
bReset : BOOL;
bLoad : BOOL;
bQu : BOOL;
bQd : BOOL;
iCount : INT;
END_VAR

ctudCount(CU := bCountUp, CD := bCountDown,
R := bReset, LD := bLoad, PV := 100);
bQu := ctudCount.QU; // 加计数到 PV 以上
bQd := ctudCount.QD; // 减计数到 0 以下
iCount := ctudCount.CV;
功能块输入输出说明
CTUCU: BOOL, R: BOOL, PV: INTQ: BOOL, CV: INT加计数器,CV ≥ PV 时 Q=TRUE
CTDCD: BOOL, LD: BOOL, PV: INTQ: BOOL, CV: INT减计数器,CV ≤ 0 时 Q=TRUE
CTUDCU, CD, R, LD: BOOL, PV: INTQU, QD: BOOL, CV: INT加减双向计数器
// 实际应用:产品计数
VAR
ctuProduct : CTU;
bSensor : BOOL; // 传感器信号(上升沿)
bResetCount : BOOL;
iTotal : INT;
bBatchFull : BOOL;
END_VAR

ctuProduct(CU := bSensor, R := bResetCount, PV := 500);
iTotal := ctuProduct.CV;
bBatchFull := ctuProduct.Q; // 满 500 件

9. 系统信息函数

获取系统信息

VAR
sSysInfo : STRING[128];
tCycle : TIME;
iTask : INT;
wIoState : WORD;
sPlcName : STRING[64];
sVersion : STRING[32];
diUptime : DINT;
rCpuLoad : REAL;
wMemFree : WORD;
END_VAR

sSysInfo := GET_SYS_INFO(SYS_INFO_PLC_NAME); // 返回 PLC 名称
tCycle := GET_CYCLE_TIME(); // 当前扫描周期(ms)
iTask := GET_TASK_INDEX(); // 当前 OB 索引号
wIoState := GET_IO_STATE(); // IO 模块状态位图

// Darra 扩展系统信息函数
sPlcName := GET_SYS_INFO(SYS_INFO_PLC_NAME); // 设备名称
sVersion := GET_SYS_INFO(SYS_INFO_VERSION); // 固件版本
diUptime := GET_SYS_INFO(SYS_INFO_UPTIME); // 运行秒数
rCpuLoad := GET_SYS_INFO(SYS_INFO_CPU_LOAD); // CPU 负载 0.0-100.0
函数返回说明
GET_SYS_INFO(SELECTOR)取决于选择器获取系统信息,选择器见下表
GET_CYCLE_TIME()TIME返回当前扫描周期时间
GET_TASK_INDEX()INT返回当前执行的组织块索引号
GET_IO_STATE()WORD返回 IO 模块状态位图

系统信息选择器常量

常量名返回类型说明
SYS_INFO_PLC_NAMESTRING设备名称
SYS_INFO_VERSIONSTRING固件版本号
SYS_INFO_UPTIMEDINT运行秒数
SYS_INFO_CPU_LOADREALCPU 负载百分比
SYS_INFO_MEM_FREEWORD剩余内存百分比
SYS_INFO_CYCLE_MINTIME最小扫描周期
SYS_INFO_CYCLE_MAXTIME最大扫描周期
SYS_INFO_TASK_COUNTINT当前活跃任务数

扫描周期监控

VAR
tCycle : TIME;
tCycleMin : TIME := T#1000ms;
tCycleMax : TIME := T#0ms;
tWatchdog : TIME;
bCycleFault : BOOL;
END_VAR

tCycle := GET_CYCLE_TIME();

// 记录扫描周期极值
IF tCycle < tCycleMin THEN tCycleMin := tCycle; END_IF;
IF tCycle > tCycleMax THEN tCycleMax := tCycle; END_IF;

// 扫描周期超限检测
IF tCycle > T#100ms THEN
bCycleFault := TRUE;
DIAG_LOG('扫描周期超限', tCycle);
END_IF;

10. 通讯函数

Darra 扩展通讯函数,用于与外部设备和服务进行数据交换。

OPC UA 通讯

VAR
bResult : BOOL;
rValue : REAL;
sError : STRING[64];
END_VAR

// 写入 OPC UA 变量
bResult := OPC_UA_WRITE(
NodeId := 'ns=2;s=电机1.转速',
Value := 1500.0,
Error := sError
);

// 读取 OPC UA 变量
bResult := OPC_UA_READ(
NodeId := 'ns=2;s=电机1.转速',
Value := rValue,
Error := sError
);
函数参数返回说明
OPC_UA_WRITE(NODE_ID, VALUE, ERROR)STRING, ANY, REF_TO STRINGBOOL写入 OPC UA 变量节点
OPC_UA_READ(NODE_ID, VALUE, ERROR)STRING, REF_TO ANY, REF_TO STRINGBOOL读取 OPC UA 变量节点

Modbus 通讯

VAR
bResult : BOOL;
aiRegs : ARRAY[0..9] OF INT;
sError : STRING[64];
END_VAR

// Modbus 读保持寄存器
bResult := MODBUS_READ(
Port := 'COM1',
SlaveId := 1,
FuncCode := 3,
Addr := 100,
Count := 10,
Data := aiRegs,
Error := sError
);

// Modbus 写单个线圈
bResult := MODBUS_WRITE(
Port := 'COM1',
SlaveId := 1,
FuncCode := 5,
Addr := 0,
Value := TRUE,
Error := sError
);
函数参数返回说明
MODBUS_READ(PORT, SLAVE_ID, FUNC, ADDR, COUNT, DATA, ERROR)见上BOOL读取 Modbus 从站数据
MODBUS_WRITE(PORT, SLAVE_ID, FUNC, ADDR, VALUE, ERROR)见上BOOL写入 Modbus 从站数据

HTTP 请求

VAR
bResult : BOOL;
sResponse : STRING[1024];
sError : STRING[64];
END_VAR

// 发送 HTTP POST 请求
bResult := HTTP_POST(
Url := 'http://192.168.1.100:5000/api/data',
Headers := 'Content-Type: application/json',
Body := '{"temperature": 25.5, "pressure": 101.3}',
Response := sResponse,
Timeout := T#5s,
Error := sError
);

// 简化版 GET 请求
bResult := HTTP_GET(
Url := 'http://192.168.1.100:5000/api/status',
Response := sResponse,
Timeout := T#3s,
Error := sError
);
函数参数返回说明
HTTP_POST(URL, HEADERS, BODY, RES, TIMEOUT, ERR)见上BOOL发送 HTTP POST 请求
HTTP_GET(URL, RES, TIMEOUT, ERR)见上BOOL发送 HTTP GET 请求
HTTP_PUT(URL, HEADERS, BODY, RES, TIMEOUT, ERR)见上BOOL发送 HTTP PUT 请求(Darra 扩展)
VAR
bResult : BOOL;
sResponse : STRING[1024];
sError : STRING[64];
END_VAR

// 向同一 Darra 网络内的另一个 PLC 发送数据
bResult := DARRA_SEND(
TargetId := '192.168.1.200',
Port := 18821,
Data := '{"command": "start", "value": 1}',
Response := sResponse,
Timeout := T#2s,
Error := sError
);
函数参数返回说明
DARRA_SEND(TARGET, PORT, DATA, RESP, TIMEOUT, ERR)见上BOOL通过 DarraLink 协议发送数据到另一 PLC

11. 诊断函数

诊断日志

VAR
bResult : BOOL;
diEventId : DINT;
tTimestamp : TIME;
END_VAR

// 写入诊断日志
bResult := DIAG_LOG(
Category := '温度监控',
Message := '电机 1 温度超限',
Severity := DIAG_WARNING
);

// 带上下文信息
bResult := DIAG_LOG(
Category := '通讯',
Message := 'Modbus 从站 1 超时',
Severity := DIAG_ERROR,
Context := 'COM1, 19200bps'
);
函数参数返回说明
DIAG_LOG(CATEGORY, MESSAGE, SEVERITY, ...)STRING, STRING, INT, ...BOOL写入诊断日志条目

诊断严重度级别

常量说明
DIAG_INFO0信息性消息
DIAG_WARNING1警告,不影响运行
DIAG_ERROR2错误,功能受限
DIAG_CRITICAL3严重错误,需立即处理

报警管理

VAR
bResult : BOOL;
diAlarmId : DINT;
sAlarmText : STRING[128];
END_VAR

// 触发报警
bResult := DIAG_ALARM(
AlarmId := 1001,
Message := '急停按钮被按下',
Severity := DIAG_CRITICAL,
AutoAck := FALSE
);

// 确认报警
bResult := DIAG_ALARM_ACK(AlarmId := 1001);

// 清除报警
bResult := DIAG_ALARM_CLR(AlarmId := 1001);

// 查询报警状态
bResult := DIAG_ALARM_QUERY(
AlarmId := 1001,
Active := bActive,
Timestamp := tTimestamp,
Text := sAlarmText
);
函数参数返回说明
DIAG_ALARM(ID, MSG, SEV, AUTOACK)见上BOOL触发报警
DIAG_ALARM_ACK(ID)DINTBOOL确认报警
DIAG_ALARM_CLR(ID)DINTBOOL清除报警
DIAG_ALARM_QUERY(ID, ACTIVE, TS, TEXT)见上BOOL查询报警当前状态

跟踪与性能分析

VAR
bResult : BOOL;
rTraceData : ARRAY[0..1023] OF REAL;
iCount : INT;
END_VAR

// 开始性能跟踪
bResult := DIAG_TRACE(
Name := 'PID_循环',
Enable := TRUE,
Interval := T#10ms,
MaxSamples := 1024
);

// 写入跟踪点
bResult := DIAG_TRACE_POINT(
Name := 'PID_循环',
Value := rProcessValue
);

// 停止并读取跟踪数据
bResult := DIAG_TRACE_READ(
Name := 'PID_循环',
Data := rTraceData,
Count := iCount
);
函数参数返回说明
DIAG_TRACE(NAME, ENABLE, INTERVAL, MAX)见上BOOL配置诊断跟踪
DIAG_TRACE_POINT(NAME, VALUE)STRING, REALBOOL写入跟踪采样点
DIAG_TRACE_READ(NAME, DATA, COUNT)STRING, ARRAY, REF_TO INTBOOL读取已采集的跟踪数据

系统诊断综合示例

PROGRAM Diagnostics
VAR
tCycle : TIME;
rCpuLoad : REAL;
bCommOk : BOOL;
bAlarmActive : BOOL;
diAlarmId : DINT;
sMsg : STRING[128];
END_VAR

// 扫描周期监控
tCycle := GET_CYCLE_TIME();
IF tCycle > T#100ms THEN
DIAG_LOG('性能', '扫描周期超限', DIAG_WARNING, TIME_TO_DINT(tCycle));
END_IF;

// CPU 负载监控
rCpuLoad := GET_SYS_INFO(SYS_INFO_CPU_LOAD);
IF rCpuLoad > 85.0 THEN
DIAG_LOG('性能', 'CPU 负载过高', DIAG_WARNING, rCpuLoad);
END_IF;

// 通讯状态监控
bCommOk := MODBUS_READ('COM1', 1, 3, 0, 1, aiTemp, sError);
IF NOT bCommOk THEN
DIAG_ALARM(2001, 'Modbus 通讯中断', DIAG_ERROR, FALSE);
END_IF;

END_PROGRAM

12. 函数调用速查表

类别函数 / FB说明
类型转换BOOL_TO_BYTE, INT_TO_DINT, DINT_TO_REAL, REAL_TO_STRING, STRING_TO_REAL, WORD_TO_DINT数据类型间转换
数学ABS, SQRT, LN, LOG, EXP, EXPT, SIN, COS, TAN, ASIN, ACOS, ATAN标准数学运算
舍入TRUNC, ROUND, CEIL, FLOOR数值舍入与截断
选择SEL, MAX, MIN, LIMIT, MUX条件选择与限幅
位操作SHL, SHR, ROL, ROR移位与循环移位
字符串LEN, LEFT, RIGHT, MID, CONCAT, FIND, INSERT, DELETE, REPLACE标准字符串操作
字符串扩展REPLACE_STR, TRIM, TO_UPPER, TO_LOWER, LPAD, RPAD, COUNT_STRDarra 扩展字符串操作
日期时间GET_DATE_TIME, GET_DATE, GET_TIME_OF_DAY, GET_RUN_TIME, DATE_TO_STRING, STRING_TO_DATE, TOD_TO_TIME, TIME_TO_TOD时间获取与转换
边缘检测R_TRIG, F_TRIG上升沿 / 下降沿检测
定时器TON, TOF, TP, TONR接通延时、关断延时、脉冲、累计
计数器CTU, CTD, CTUD加、减、加减双向计数
系统信息GET_SYS_INFO, GET_CYCLE_TIME, GET_TASK_INDEX, GET_IO_STATE系统状态查询
通讯OPC_UA_WRITE, OPC_UA_READ, MODBUS_READ, MODBUS_WRITE, HTTP_POST, HTTP_GET, DARRA_SEND外部通讯接口
诊断DIAG_LOG, DIAG_ALARM, DIAG_ALARM_ACK, DIAG_ALARM_CLR, DIAG_TRACE日志、报警、跟踪

相关文档