在PLC(如CODESYS、TIA Portal、Twin CAT等)中对 REAL 或 LREAL 数据类型进行小数位保留,核心方法是 缩放取整法。由于PLC通常没有直接的“保留小数位”函数,需要通过数学运算实现。以下是详细说明、示例及封装的功能块。
实现原理
- 放大:将原值乘以 10^n(n为要保留的小数位数)。
- 取整:对放大后的值进行四舍五入或截断。
- 缩小:将取整后的值除以 10^n ,得到目标精度的值。
关键函数:ROUND(四舍五入)或 TRUNC(截断)。推荐使用 ROUND 更符合常规需求。
先拆解核心步骤:假设要保留n位小数,就需要把原数值乘以10^n,取整后再除以10^n。但要注意REAL类型的精度问题,比如100.0在计算机里可能是99.9999999,所以取整前要加个微小补偿值(比如0.00001)避免截断错误。
程序示例
保留2位小数:
VAR
originalValue: REAL := 123.4567;
scaledValue: REAL;
roundedValue: REAL;
result2: REAL;
END_VAR
scaledValue := originalValue * 100; // 放大100倍 (10^2)
roundedValue := ROUND(scaledValue); // 四舍五入取整
result2 := roundedValue / 100; // 缩小100倍
// result2 = 123.46
保留3位小数:
scaledValue := originalValue * 1000; // 放大1000倍 (10^3)
roundedValue := ROUND(scaledValue);
result3 := roundedValue / 1000;
// result3 = 123.457
封装功能块:FB_ScaleRound
功能块一:
FUNCTION_BLOCK FB_ScaleRound
VAR_INPUT
Value: REAL; // 原始值
Decimals: INT; // 要保留的小数位数 (0-7)
END_VAR
VAR_OUTPUT
Result: REAL; // 处理后的结果
END_VAR
VAR
Factor: REAL := 1.0;
END_VAR
// 计算缩放因子 (10^Decimals)
Factor := POWER(10, Decimals);
// 缩放 → 四舍五入 → 还原
Result := ROUND(Value * Factor) / Factor;
功能块一应用举例:
PROGRAM MAIN
VAR
fbRound2: FB_ScaleRound;
fbRound3: FB_ScaleRound;
output2, output3: REAL;
END_VAR
fbRound2(Value := 123.4567, Decimals := 2);
output2 := fbRound2.Result; // = 123.46
fbRound3(Value := 123.4567, Decimals := 3);
output3 := fbRound3.Result; // = 123.457
功能块二:
FUNCTION FC_REAL_DEAL : LREAL
VAR_INPUT
In_lreal: LREAL;
In_usint: USINT;
END_VAR
In_usint:=LIMIT(0,In_usint,7); (*精确到小数点后面第几位*)
FC_REAL_DEAL:=LREAL_TO_DINT(In_lreal*EXPT(10,In_usint) )/EXPT(10,In_usint);
注意事项
- 精度限制:REAL 类型有效位数约6-7位,LREAL 约15位。避免对超大数操作。
- 负数处理:ROUND 函数在IEC标准中兼容负数(如 -1.5 → -2.0)。
- 边界检查:可增加对 Decimals 的约束(如限定0-7)。
- 优化:频繁调用时,可预先计算缩放因子表提升效率。