1.瞬时(100ms)流量:=小时流量/36000.0;//real:瞬时流量,小时流量
2.累积流量1:=瞬时流量+累积流量1;//real:累积流量1
3.数据1:=累积流量1四舍五入取整;//DI:数据1,满10万进位并清0
4.累积流量1>=99999.9则数据2:=L#1+数据2,瞬时流量:=0.0,累积流量1:=0.0;
5.累积流量:=数据2*100000+数据1;//DI:累积流量,数据1;
6.累积流量>=99999999//累积流量>1亿自动清0;
则 累积流量:=L#0,累积流量1:=L#0,数据2:=L#0,瞬时流量:=0.0,
转个示例:
FUNCTION_BLOCK "FLUX_base"
TITLE = 'FLUXbase'
//流量累积计算
//
//算法原理:
// 当前积分量 = 积分量 + 以前的计算误差
// 当前累积量 = 当前积分量 + 原累积量
// 当前计算误差 = 原累积量 - 当前累积量 + 当前积分量
//
//版本: 1.2
//作者: QLHCCO
//创建: 2008.05.09 V1.0
//更新: 2008.05.15 V1.1
//更新: 2008.05.15 V1.2
// v1.2版本的更新变动较大,在精度处理方面还是原来的思想,在输出显示方面
// 采用了DINT数据类型,修正数据超过7位数时个位无法显示的问题。
//
VERSION: '1.2'
AUTHOR: qlhcco
NAME: FLUXbase
FAMILY: FLUX
VAR_INPUT
RS : BOOL := FALSE ; //初始化(手动)
PV : REAL := 0.0 ; //瞬时流量
CYC : REAL := 100.0 ; //采样时间(MS)
PLL : REAL := 0.0 ; //允许的最小瞬时流量
END_VAR
VAR_IN_OUT
OV : DINT := 0 ; //累积量输出
OV_MIN : REAL := 0.0 ; //累积量<1.0
ERROR : REAL := 0.0 ; //累计误差
PV_ALT : REAL := 0.0 ; //上周期瞬时流量
END_VAR
VAR_TEMP
tbRS : BOOL ; //初始化
Average : REAL ; //瞬时平均值
Integral : REAL ; //当前积分量
OVminFlk : REAL ; //上周期小累积量
trOVmin : REAL ; //当前累积量<1.0
trError : REAL ; //当前累计误差
OVminDint : DINT ; //当前小累积量长整型表示
trOV : DINT ; //当前累积量
END_VAR
trOV := OV ;
OVminFlk := OV_MIN ;
trOVmin := OV_MIN ;
trError := ERROR ;
Average := ( PV + PV_ALT ) / 2.0 ;
tbRS := trOV >= 2000000000 AND trOVmin >= 0.0 OR RS;
IF tbRS THEN //初始化
trOV := 0 ;
OVminFlk := 0.0 ;
trOVmin := 0.0 ;
trError := 0.0 ;
END_IF;
IF Average >= PLL THEN //小信号切除
//注:为什么误差(ERROR)加到积分(Integral)里,而不是加到累积量(OV_MIN)
//在浮点数计算的加减有一个原则,加法时,小数值与小数值与小数值先相加
//然后再加大数值的数据,减法时,大数值先相减,然后加减小数值.
Integral := Average * ( CYC / 3.6E+6 ) + trError ; //计算当前积分量
trOVmin := Integral + OVminFlk ;
trError := OVminFlk - trOVmin + Integral ; //误差动态误差计算
ELSE
trOVmin := OVminFlk ;
END_IF ;
OVminDint := REAL_TO_DINT( trOVmin ) ; //取出OV_MIN的整数部分
OV := trOV + OVminDint ;
OV_MIN := trOVmin - DINT_TO_REAL( OVminDint ) ; //将OV_MIN的整数部分去除,留下小数部分
ERROR := trError ;
PV_ALT := PV ;
END_FUNCTION_BLOCK
以上是原程序,编译下就可以变成功能块了