上次有网友提到过这个循环调用FC105处理模拟量输入的问题,做项目时也亲身体会到,手动1个个调用FC105的手指头痛。该程序的目的是将读取的如IW256,IW258等经过FC105处理后,将结果放置到DB里。经过2个项目实际使用后,可以用哈,分享给大家。
DB3里放置的都是Struct,用于设置参数,Struct的名字就是位号了,如LT1401,LT1402,元素如下
PV_IN : INT ; //偏移2
PV_HR : REAL ; //6
PV_LR : REAL ; //10
Bipolar : BOOL ;//12
RET_VAT : WORD ;//14
PV_OUT : REAL ;//18
如LT1401.PV_OUT就是经FC105处理后的过程值了。
FUNCTION "AIScale" : VOID
TITLE = Analog Input
AUTHOR : NC
FAMILY : Channel
NAME : AI
VERSION : 0.1
VAR_INPUT
HWStartAddress : INT ; //硬件地址输入起始位置如 256
DBStartAddress : ANY ;//存储的DB号和DB偏移位置信息,如DB3.DBB 0
Number : INT ; //通道数量 如48,即6个8AI模块
END_VAR
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VAR_TEMP
Parameter : STRUCT // FC105的参数暂存,
PV_IN : INT ;
PV_HR : REAL ; //初始值设置为100.0
PV_LR : REAL ; //~~~0.0
Bipolar : BOOL ; //~~单极性
RET_VAT : WORD ;
PV_OUT : REAL ;
END_STRUCT ;
Cyclic : BYTE ; //循环调用FC105的次数
AR2_Save : DWORD ; //存取AR2
DB_Number : WORD ; //获取存储的DB号
END_VAR
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BEGIN
NETWORK
TITLE =
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TAR2 ;
T #AR2_Save; //保存AR2信息
L P##DBStartAddress; //获取目标DB的地址信息,假设填写的是DB3.DBB 0
LAR1 ;
L #HWStartAddress; //获取硬件地址信息
SLD 3;
LAR2 ;
L W [AR1,P#4.0]; // Datablock Number , ANY指针的第4,5字节存取的是填写在接口的DB号"3"
T #DB_Number;
L W [AR1,P#8.0]; // Address Offset Information ,ANY指针的第8字节存取的偏移"0"
SRD 3;
SLD 3;
LAR1 ;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OPN DB [#DB_Number]; //打开DB3
L #Number;
NEXT: T #Cyclic; //通道数即循环调用FC105的次数
L PIW [AR2,P#0.0]; //给FC105的接口赋值,读取DB3里的每个通道参数设置,测量范围,极性等
T #Parameter.PV_IN;
T DBW [AR1,P#0.0];
L DBD [AR1,P#2.0];
T #Parameter.PV_HR;
L DBD [AR1,P#6.0];
T #Parameter.PV_LR;
A DBX [AR1,P#10.0];
= #Parameter.Bipolar;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CALL "SCALE" ( //调用FC105,循环100次,接口参数会更新100次,进而有100次输出结果
IN := #Parameter.PV_IN,
HI_LIM := #Parameter.PV_HR,
LO_LIM := #Parameter.PV_LR,
BIPOLAR := #Parameter.Bipolar,
RET_VAL := #Parameter.RET_VAT,
OUT := #Parameter.PV_OUT);
L #Parameter.RET_VAT;
T DBW [AR1,P#12.0];
L #Parameter.PV_OUT; //输出结果,过程值
T DBD [AR1,P#14.0];
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AR1 P#18.0; //DB3的Struct换到下一个通道,如LT1401到LT1402
+AR2 P#2.0; //硬件地址偏移2
L #Cyclic;
LOOP NEXT;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
L #AR2_Save; //恢复AR2
LAR2 ;
SET ;
SAVE ;
END_FUNCTION

小结:
这种方法的缺点:
硬件地址需要连续,不然的话需要多次调用,做设计的时候最好把一个柜子的所有的AI都放连续的。
单个模块里通道需要都适应FC105,如有些通道是开平方的,不是调用FC105,这种情况也要分开调用该功能块。