希殿电气技术(上海)有限公司(西门子经销商)
联系人 :康经理(销售工程师)发布
前几天发了一个提问怎么读写1200/1500DB数据块的求答案,没人回答,我查阅了相关的帮助,在博图中编写300/400PLC是支持DB_BLOCK数据类型的,而1200和1500不支持该类型.也就是说在博图中SCL编程针对不同系列的PLC是不一定通用的.这点需要大家注意.以下是博图中的模拟量批量转换的SCL程序给喜欢偷懒的提高销量的同行研究哈,若有什么BUG请告知.该程序通过仿真实验.
本程序比较适合连续AI地址的情况,DB块赋值也较为方便(可采用EXCEL编辑粘贴为原代码)
20170929修改一个BUG:即当通道超出范围报错时,该转换值会使用错误的值更正代码如下
FUNCTION_BLOCK "模拟量转换"
TITLE = 模拟量输入转换
{ S7_Optimized_Access := 'FALSE' }
AUTHOR : EBCLW
FAMILY : EBC
NAME : AI_OUT
VERSION : 1.0
//
// 模拟量输入量程批量转换
//
// Block Parameters
VAR_INPUT
ADDRESS : Int := 512; // 开始的PIW地址
NUM : Int := 1; // 仪表数量即多少个PIW地址
DATA_NUM : DInt; // 用于存放数据的量程 偏差设定
VALUE_NUM : DInt; // 存放输出结果
END_VAR
VAR
K1 : Real;
K2 : Real;
END_VAR
VAR_TEMP
I : DInt; // 循环变量
IW_INT_VAL : Int;
IW_VAL : Real;
HI_VAL : Real;
LI_VAL : Real;
OF_VAL : Real;
DIP_VAL : Byte;
TEMP : Real;
END_VAR
BEGIN
//###########################################################
//采用FC105相同的计算公式OUT = ((FLOAT (IN) -K1)/(K2-K1)) * (HI_LIM-LO_LIM) + LO_LIM
//增加一个修正偏差公式改为OUT = ((FLOAT (IN) -K1)/(K2-K1)) * (HI_LIM-LO_LIM) + LO_LIM + OFFSET
//循环批量转换循环体
//##########################################################
//参数DB块数据结构
(*
H:REAL 量程上限设定值
L:REAL 量程下限设定值
OF:REAL 修正偏差设定值
DIP:BYTE双极性设置
:
:
:
*)
//输出参数DB块数据结构
(*
VALUE:REAL 转换后输出值
ERR:BYTE 错误值 通道值超出范围即输出0位为1
:
:
:
*)
FOR #I := 1 TO #NUM BY 1 DO
//读取IW地址以及数据块的参数
//------------------------------------------
#IW_INT_VAL := WORD_TO_INT(PEEK_WORD(area := 16#81, dbNumber := 0, byteOffset := #ADDRESS + (#I - 1) * 2));//数据有正负性,必须转换为INT格式
#IW_VAL := DINT_TO_REAL(INT_TO_DINT(#IW_INT_VAL));
#HI_VAL :=DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14));
#LI_VAL := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 4));
#OF_VAL := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 8));
#DIP_VAL:=PEEK_BYTE(area := 16#84, dbNumber := #DATA_NUM, byteOffset := (#I - 1) * 14 + 12);
//-------------------------------------------
//判断是否是双极性
//读取数据库参数判断是否是双极性,0为单极性,1为双极性并判断通道值是否溢出
//-----------------------------------------------------
IF #DIP_VAL>=16#1 THEN
//双极性
#K1 := -27648.0;
#K2 := 27648.0;
//读取IW数值通过数值判断数值是否异常若异常则将异常状态写入数据块,异常就给错误字0位写1
IF #IW_INT_VAL <= -27649 OR #IW_INT_VAL >= 27649 THEN
POKE_BOOL(area := 16#84,
dbNumber := #VALUE_NUM,
byteOffset := (#I - 1) * 6 + 4,
bitOffset := 0,
value := TRUE);
//不在量程范围内则读取当前输出的值给TEMP变量
#TEMP := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #VALUE_NUM, byteOffset := (#I - 1) * 6));
//不在量程范围内输出为0;
// #TEMP := 0.0;
ELSE
POKE_BOOL(area := 16#84,
dbNumber := #VALUE_NUM,
byteOffset := (#I - 1) * 6 + 4,
bitOffset := 0,
value := FALSE);
//若在量程范围内就做量程转换
//#TEMP := (#IW_VAL - #K1) / (#K2 - #K1) * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
//算法优化
#TEMP := (#IW_VAL +27648.0) /55296.0 * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
END_IF;
ELSE
//单极性
#K1 := 0.0;
#K2 := 27648.0;
//读取IW数值通过数值判断数值是否异常若异常则将异常状态写入数据块,异常就给错误字0位写1
IF (#IW_INT_VAL >= 27649) OR (#IW_INT_VAL<=-1) THEN
// IF #IW_INT_VAL<=-1 THEN
POKE_BOOL(area := 16#84,
dbNumber := #VALUE_NUM,
byteOffset := (#I - 1) * 6 + 4,
bitOffset := 0,
value := TRUE);
//不在量程范围内则读取当前输出的值给TEMP变量
#TEMP := DWORD_TO_REAL(PEEK_DWORD(area := 16#84, dbNumber := #VALUE_NUM, byteOffset := (#I - 1) * 6));
//不在量程范围内输出为0;
// #TEMP := 0.0;
ELSE
POKE_BOOL(area := 16#84,
dbNumber := #VALUE_NUM,
byteOffset := (#I - 1) * 6 + 4,
bitOffset := 0,
value := FALSE);
//若在量程范围内就做量程转换
//#TEMP := (#IW_VAL - #K1) / (#K2 - #K1) * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
//算法优化
#TEMP := #IW_VAL / 27648.0 * (#HI_VAL - #LI_VAL) + #LI_VAL + #OF_VAL;
END_IF;
END_IF;
//-------------------------------------------------------
POKE(area := 16#84,
dbNumber := #VALUE_NUM,
byteOffset := (#I-1)*6,
value := REAL_TO_DWORD(#TEMP));
END_FOR;
END_FUNCTION_BLOCK
模拟量输入参数DB块源代码BEGIN赋值代码很好的能在EXCEL中进行编辑,对于大批量的设置参数有很用的
--------------
DATA_BLOCK "模拟量输入参数"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
STRUCT
CS : Array[0..10] of Struct
H : Real;
L : Real;
OFF : Real;
DIP : Byte;
END_STRUCT;
END_STRUCT;
BEGIN
CS[0].H := 200.678;
CS[1].H := 100.0;
CS[2].H := 100.0;
CS[3].H := 100.0;
CS[4].H := 100.0;
END_DATA_BLOCK
-------------------------------------------
模拟量输出DB块源代码 源代码生成块后直接设置数组的数量即可
-----------------------------------
DATA_BLOCK "模拟量输出"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
STRUCT
OUT : Array[0..10] of Struct
VALUE : Real;
ERR : Byte;
END_STRUCT;
END_STRUCT;