找答案的高端用户(找答案钻石及双钻级别的用户)将尽可能从此问题下的所有回
答中,为您推荐最佳答案。届时您可以根据推荐数采纳答案。
如果自提问时间起7天内您仍无法选出最佳答案,您可以选择“无满意答案”关闭此问题。
1、附的程序是针对实数的,采样存储在数据块中;
2、在数据块数据块中开定义中先进先出,存储100个值,先进先出。
实现方式如下
定义一个FC组织块
程序段1:判断传递指针的正确性
不是 ANY 类型的指针,返回值为1,不是 REAL 型数据,返回值为2
不是数据块,返回值为3
L P##Address //装载主程序中的指针到累加器1
LAR1 //将累加器1中的内容装载到AR1
L B [AR1,P#0.0] //装载ANY参数类型中字节1容到累加器1
L B#16#10 //装载 16#10 到累加器2
<>I //比较 传递的 ANY 指针的第1个字节是不是合法的 16#10,如果是则说明指针是80位的ANY类型的指针,如果不是则指针传递错误。
JC _001 //如果第1个字节是不是合法的 16#10,则指针传递不正确跳转并返回错误状态值为1
L B [AR1,P#1.0] //装载ANY参数类型中字节2到累加器1
L B#16#8 //装载 16#08 到累加器2
<>I //比较传递的 ANY 指针的第2字节是不是 16#08,如果是则说明指针传递的数据类型是REAL型
JC _002 //如果第2字节是不是 16#08,则指针传递的数据类型不是REAL型,跳转并返回错误状态值为2
L B [AR1,P#6.0] //装载ANY参数类型中字节6到累加器1
L B#16#84 //装载 16#84 到累加器2
<>I //比较 传递的 ANY 指针的第6字节是不是 16#84,如果是则说明指针传递的存储区是数据块
JC _003 //如果第6字节是不是 16#84,则指针传递的存储区不是DB块,跳转并返回错误状态值为3
程序段2:循环
L P##Address //装载主程序中的指针到累加器1
LAR1 //将累加器1中的内容装载到AR1
L W [AR1,P#4.0] //装载ANY参数类型中字3到累加器1,从指针中取DB块号
T #DB_NO
OPN DB [#DB_NO]
L #PIW_Real
T #SUM_REAL //初始化累加和。将本次扫描周期的实测值作为累加和的初始值
L W [AR1,P#2.0] //装载ANY参数类型中字2到累加器1,从指针中取循环次数
T #LOOP_COUNT
L D [AR1,P#6.0] //装载ANY参数类型中字4到累加器1,从指针中取32位指交叉指针
LAR1
L #LOOP_COUNT //装循环次数到累加器1
L 1
-I //循环次数减1
NEXT: T #LOOP_COUNT
L D [AR1,P#4.0] //装载数据块中的,当前指针指向的下一个实数,传送到当前指针指向的位置
T D [AR1,P#0.0]
L D [AR1,P#0.0] //装载本次循环要加的实数
L #SUM_REAL //装载累加和
+R //实数累加
T #SUM_REAL //保存本次累加和
+AR1 P#4.0 //指针移动P#4。0,使之指向下一个实数的地址
L #LOOP_COUNT //装载循环次数
LOOP NEXT //循环次数自动减1,减完后如果不为0,则跳转到标号NEXT继续循环
L #PIW_Real //装载本扫描周期的实测值
T D [AR1,P#0.0] //将本扫描周期的实测值传送到指针所指的位置
L #SUM_REAL //装载计算出的累加和,并求出平均数。
L 1.000000e+002
/R
T #PIW_REAL_OUT
L 0 //正常处理结束,状态字为0
T #Statues
JU _END
程序段3:指针传递出错时的状态字处理
_001: L 1 //ANY指针传递,指针第1字节不是合法的 16#10
T #Statues
JU _END
_002: L 2 //ANY指针传递,指针第2字节不是合法的 16#08,也就是数据类型不是REAL
T #Statues
JU _END
_003: L 3 //ANY指针传递,指针第7字节不是合法的 16#84,也就是存储区不是DB块
T #Statues
_END: BE
参考资料:
西门子STL间接寻址常问问题集 76492353 2013年8月8日
https://support.industry.siemens.com/cs/document/76492353
用ANY指针进行平均值运算对性ID:19345299 发布日期 2005年7月4日
https://support.industry.siemens.com/cs/document/19345299
FUNCTION_BLOCK mxlFB_filter
know_how_protect
VAR
enable_old :BOOL;
sample_count :INT; // 每次采样需要的OB35周期数
sample_number :INT; // 采样点数
count :INT; // OB35周期数
i :INT;
j :INT;
value :ARRAY [0..999] OF REAL;
value_old :REAL;
value_temp :REAL;
sample_number_2 :INT; // 采样点数
END_VAR
VAR_INPUT
in_enable :BOOL; // 使能
in_value :REAL; // 输入
in_filter_time :REAL; // 滤波时间
in_sample_time :REAL; // 采样时间
in_ob35_time :REAL:=0.1; // OB35时间
in_error :REAL; // 偏差率%
END_VAR
VAR_OUTPUT
out_value :REAL;
END_VAR
IF in_enable AND (enable_old<>in_enable) THEN
sample_count := REAL_TO_INT(in_sample_time/in_ob35_time); // 每次采样需要的周期数
sample_number := REAL_TO_INT(in_filter_time/in_sample_time); // 采样点数
END_IF;
IF in_enable THEN
count := count+1;
IF count>sample_count THEN
value_temp :=0.0;
// ……[3]-->[2];[2]-->[1];[1]-->[0]
FOR i:= 1 TO (sample_number-1) BY 1 DO
value[i] := value[i+1];
END_FOR;
value[sample_number] := in_value;
FOR j:= 1 TO (sample_number) BY 1 DO
value_temp := (value_temp+value[j]);
END_FOR;
out_value := value_temp/sample_number;
count := 0;
END_IF;
ELSE
out_value := 0.0;
count := 0;
sample_count :=0;
sample_number :=0;
sample_number_2 := 0;
END_IF;
首次回答问题,获得
双倍西币积分!
立即成为技术知识分享的一员!
找答案微信小程序
提问
搜索
欢迎您访问支持中心!
丰富的视频,全方位的文档,大量的网友交流精华……
为了更好的完善这些内容,我们诚邀您在浏览结束后,花20秒左右的时间,完成一个用户在线调查!
感谢您的支持!