第一章 Oto数据类型IO结构体
前言
hans是头部支撑的意思
常量用于给到数组变量,不可在线更改–hans
变量类型用于给到编辑区使用,可以随时在线更改修改–hans
创建用户变量g_arUserVar,工作流程信息g_tWorkFlowInfo结构体,刷新读写的区域数据。自动流程的所有操作都需要操作g_tWorkFlowInfo内变量–hans
PLC_Init系统初始化用于对初始化IO参数:读取或者写入,IO配置参数,本地4入4出+扩展的4个模块,同时默认配置IO属性–hans
PLC_IO用于对IO和系统状态的映射,扩展映射-比如急停信号未用,需要映射变量、遥控器485通信、手持盒–hans
一、IO的数据结构
1. Tag_IO_Input_Prm
TYPE Tag_IO_Input_Prm :
STRUCT
iModuleID : INT:=0; (*模块号:0为本地:1为扩展模块1...*)
iPortID : INT:=0; (*端口号:0 ~ 端口计数-1*)
iActivLevel : INT:=0; (*有效电平:0 / 1 *)
uiNoteID : UINT:=0; (*注释Id*)
iSetFilterTimes : INT := CNST_IO_FILTER_TIMES; (*设定滤波次数*)
bFilterPreVal : BOOL:=0; (*滤波记录*)
bFilterCurVal : BOOL:=0;
iCurFilterTimes : INT:=0;
iRecFilterTimes : INT:=0;
END_STRUCT
END_TYPE
2. Tag_IO_Output_Prm
TYPE Tag_IO_Output_Prm :
STRUCT
iEnable : INT:=1;
iModuleID : INT:=0; (*模块号:0为本地:1为扩展模块1...*)
iPortID : INT:=0; (*端口号:0 ~ 端口计数-1*)
iActivLevel : INT:=0; (*有效电平:0 / 1 *)
uiNoteID : UINT:=0; (*注释Id*)
iMonitor : INT:=0; (*是否检知:0不检:1检*)
iMonitorIOIndex : INT:=0; (*检知的IO在其数组中索引:1 ~ 输入点个数*)
lrBegDelayTime_Sec : LREAL:=0; (*当前检知延时:秒*)
lrDelayTime_Sec : LREAL:=0; (*检知延时:秒*)
END_STRUCT
END_TYPE
3. Tag_IO_Input_STS
TYPE Tag_IO_Input_STS :
STRUCT
bCurStatus : BOOL;(*IO当前状态:1:有效,0:无效*)
END_STRUCT
END_TYPE
4. Tag_IO_Output_STS
TYPE Tag_IO_Output_STS :
STRUCT
bSetStatus : BOOL; (*IO输出状态*)
bCurStatus : BOOL; (*IO当前状态*)
END_STRUCT
END_TYPE
二、全局变量
1.Global_Variables_IO_lib
(*常量用于给到数组变量,不可在线更改--hans*)
VAR_GLOBAL CONSTANT
CNST_IO_FILTER_TIMES : INT := 3; (* 输入信号滤波次数 *)
END_VAR
(*变量类型用于给到编辑区使用,可以随时在线更改修改--hans*)
VAR_GLOBAL
(*------------IO状态----------*)
STS_IO_INPUT : ARRAY[1..CNST_INPUT_COUNT] OF Tag_IO_Input_STS;
STS_IO_OUTPUT : ARRAY[1..CNST_OUTPUT_COUNT] OF Tag_IO_Output_STS;
(*-------------IO配置参数----------------*)
g_atIO_Input_Prm :ARRAY[1..CNST_INPUT_COUNT] OF Tag_IO_Input_Prm;
g_atIO_Output_Prm :ARRAY[1..CNST_OUTPUT_COUNT] OF Tag_IO_Output_Prm;
END_VAR
2.g_atIO_Input_Prm
3.g_atIO_Output_Prm
4.STS_IO_INPUT
5.STS_IO_OUTPUT
6.编译出错
7.添加全局变量Global_System_IO
(*常量用于给到数组变量,不可在线更改--hans*)
VAR_GLOBAL CONSTANT
CNST_INPUT_COUNT : INT:= 52; (* 输入点计数 *)(* --------------------可修改--------------------- *)
CNST_OUTPUT_COUNT : INT:= 28; (* 输出点计数 *)(* --------------------可修改--------------------- *)
END_VAR
VAR_GLOBAL
END_VAR
三、初始化Init_IO
3.1 Init_IO
初始化IO参数:读取或者写入,IO配置参数,本地4入4出+扩展的4个模块,同时默认配置IO属性–hans
(读取IO模块物理地址–hans)
(读取输入配置*******)
Init_Input;
(读取输出配置************)
Init_Output;
(写入输入配置***)
(写入输出配置********)
3.2 Init_Input
(添加注释ID号)
(输入信号属于本地输入信号)
(输入信号属于拓展模块信号)
(写入输入配置)
j :=1;
FOR i:=1 TO CNST_INPUT_COUNT BY 1 DO
(*添加注释ID号*)
g_atIO_Input_Prm[i].uiNoteID := i + 12000;(*注释ID从12000开始*)
(*输入信号属于本地输入信号*)
IF i >= 1 AND i<= CNST_LOCAL_INPUT_COUNT THEN(*本地IO属性*)
g_atIO_Input_Prm[i].iModuleID := 0;
g_atIO_Input_Prm[i].iPortID := i-1;(*端口号从0开始,0~4*)
g_atIO_Input_Prm[i].iActivLevel := 0;(*有效电平*)
ELSE
(*输入信号属于拓展模块信号*)
iTemp := i - CNST_LOCAL_INPUT_COUNT - (j-1)*CNST_EXT_MODULAR_INPUT_COUNT - 1;
g_atIO_Input_Prm[i].iModuleID := j;
(*5~20--j=1,则iTemp=0~15,21~36--j=2,itemp=0~15,37~52--j=3,itemp=0~15*)
g_atIO_Input_Prm[i].iPortID := iTemp;
g_atIO_Input_Prm[i].iActivLevel := 1; (*扩展模块有效电平*)
IF iTemp >= (CNST_EXT_MODULAR_INPUT_COUNT-1) THEN
j :=j + 1;
END_IF
END_IF
END_FOR
(*写入输入配置*)
dwFile := SysFileOpen(g_str_InputPrmFilePath, 'w');
IF dwFile = 0 THEN
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
dwTemp := SIZEOF(g_atIO_Input_Prm);
IF dwTemp <> SysFileWrite(dwFile, ADR(g_atIO_Input_Prm[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;
3.3 Init_Output
(IO输出注释ID)
(属于本地IO输出状态)
(拓展IO输出状态)
(写入输出配置)
j :=1;
FOR i:=1 TO CNST_OUTPUT_COUNT BY 1 DO
(*IO输出注释ID*)
g_atIO_Output_Prm[i].uiNoteID := i+ 13000;
(*属于本地IO输出状态*)
IF i >= 1 AND i<= CNST_LOCAL_OUTPUT_COUNT THEN
g_atIO_Output_Prm[i].iModuleID := 0;
g_atIO_Output_Prm[i].iPortID := i-1;
g_atIO_Output_Prm[i].iActivLevel := 0;
ELSE
(*拓展IO输出状态*)
iTemp := i - CNST_LOCAL_OUTPUT_COUNT - (j-1)*CNST_EXT_MODULAR_OUTPUT_COUNT - 1;
g_atIO_Output_Prm[i].iModuleID := j;
g_atIO_Output_Prm[i].iPortID := iTemp;
g_atIO_Output_Prm[i].iActivLevel := 1; (*扩展模块有效电平*)
IF iTemp >= (CNST_EXT_MODULAR_OUTPUT_COUNT-1) THEN
j :=j + 1;
END_IF
END_IF
END_FOR
(*写入输出配置*)
dwFile := SysFileOpen(g_str_OutputPrmFilePath, 'w');
IF dwFile = 0 THEN
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
dwTemp := SIZEOF(g_atIO_Output_Prm);
IF dwTemp <> SysFileWrite(dwFile, ADR(g_atIO_Output_Prm[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;
四、PLC_IO和系统状态的映射
(*--------------------IO界面----------------------------------*)
g_fbIO_SET : IO_SET; (*IO状态*)
g_fbIO_SET_Ctrl : IO_SET_Ctrl; (*IO状态*)
4.1 IO_SET
(读取IO配置文件)
ReadIOamount;
ReadIOset;
ReadIO_UserVar;
ReadIO_station;
(界面参数设定)
UerVar_Ctrl;
(IO模块配置)
(手动控制)
(进入编辑模式)
(编辑站号,IO设置)
(修改输入输出)
(修改当前站号)
(修改关联变量)
(保存)
(保存站号,IO设置等信息)
write_data;
(翻页)
(区分IO模块和glink200模块)
(模块数量修改)
4.1.1 ReadIO_station
(****************************读取IO站号**************************)
(*轴标准文件大小*)
(*当前文件大小与标准文件大小不一致,报警*)
(*轴文件大小*)
(*打开轴文件*)
(*读取轴文件参数*)
4.1.2 ReadIO_UserVar
(****************************读取IO关联变量**************************)
(*轴标准文件大小*)
(*当前文件大小与标准文件大小不一致,报警*)
(*轴文件大小*)
(*打开轴文件*)
(*读取轴文件参数*)
4.1.3 ReadIOamount
(****************************读取IO数量**************************)
diTemp := SysFileGetSize(str_IOamountPath);
(*轴标准文件大小*)
diTemp1 := 4;
(*当前文件大小与标准文件大小不一致,报警*)
ALARM_GET[10,9] :=TRUE;
bReadErr[1] := TRUE;
ELSE
(*轴文件大小*)
dwTemp := DINT_TO_DWORD(diTemp);
(*打开轴文件*)
dwFile := SysFileOpen(str_IOamountPath, 'r');
ALARM_GET[10,9] :=TRUE;
bReadErr[2] := TRUE;
ELSE
(*读取轴文件参数*)
IF dwTemp <> SysFileRead(dwFile, ADR(IOamount[1]), dwTemp) THEN
ALARM_READ_PRM_FILE := TRUE;ALARM_GET[10,9] :=TRUE;
bReadErr[3] := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
END_IF
dwFile := 0;
4.1.4 ReadIOset
(****************************读取IO设置**************************)
(*轴标准文件大小*)
(*当前文件大小与标准文件大小不一致,报警*)
(*轴文件大小*)
(*打开轴文件*)
(*读取轴文件参数*)
4.1.5 UerVar_Ctrl
(*IO板关联*)
FOR i := 1 TO IOamount[1] DO
FOR j := 1 TO 16 DO
Temp1 := IO_UserVar[16*i+j-16];
IF Temp1 <> 0 THEN
IF IOset[16*i+j-16] =0 THEN
IF GTN_GetDiPhysicCustom(1, IO_station[i], MC_GPI, j, ADR(divalue[j]), 1)<>0 THEN
ALARM_GET_DI := TRUE;ALARM_GET[7,1] := TRUE;
(*RETURN;*)
END_IF
(*对孔滤波*)
IF Temp1 =56 THEN
IF L = 0 THEN
L := L+1;
b_prev := divalue[j];
ELSE
IF L <2 THEN (*滤波次数*)
IF b_prev = divalue[j] THEN
L := L+1; (*次数加一*)
ELSE(*数据错误重新开始计数*)
L :=0;
END_IF
END_IF
END_IF
IF L =2 THEN(*2次滤波结束*)
g_arUserVar[Temp1] := 1-divalue[j];(*发送数据*)
L := 0; (*滤波次数清零*)
END_IF
ELSE
g_arUserVar[Temp1] := 1-divalue[j];
END_IF
ELSE
IF g_arUserVar[Temp1] =1 THEN
Temp2 := 0;
IF GTN_SetDoPhysicCustom(1, IO_station[i], MC_GPO, j, ADR(Temp2), 1)<> 0 THEN
ALARM_SET_DO := TRUE;ALARM_GET[9,1] :=TRUE;
(* RETURN;*)
END_IF
ELSE
Temp2 := 1;
IF GTN_SetDoPhysicCustom(1, IO_station[i], MC_GPO, j, ADR(Temp2), 1)<> 0 THEN
ALARM_SET_DO := TRUE;ALARM_GET[9,1] :=TRUE;
(* RETURN;*)
END_IF
END_IF
END_IF
END_IF
END_FOR
END_FOR
win[1] := win1;
win[2] := win2;
win[3] := win3;
win[4] := win4;
(*Glink200关联*)
IF IOamount[2]<> 0 THEN
FOR i := 1 TO IOamount[2] DO
FOR j :=1 TO 16 DO
Temp1 := IO_UserVar[32*i+j-32+16*IOamount[1]];
IF Temp1 <> 0 THEN
g_arUserVar[Temp1] := WORD_TO_REAL(SHR(win[i],j-1) AND 1);
END_IF
END_FOR
FOR j := 17 TO 32 DO
Temp1 := IO_UserVar[32*i+j-32+16*IOamount[1]];
IF Temp1 <> 0 THEN
IF (SHR(wout[i],j-17) AND 1) <>0 THEN
IF g_arUserVar[Temp1] = 0 THEN
wout[i] := wout[i] - REAL_TO_WORD(EXPT(2,j-17));
END_IF
ELSE
IF g_arUserVar[Temp1] = 1 THEN
wout[i] := wout[i] + REAL_TO_WORD(EXPT(2,j-17));
END_IF
END_IF
END_IF
END_FOR
END_FOR
END_IF
wout1 := wout[1];
wout2 := wout[2];
wout3 := wout[3];
wout4 := wout[4];
4.1.6 write_data
dwFile := SysFileOpen(str_IO_stationPath, 'w');
IF dwFile = 0 THEN
(*读取标定文件报警*)
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
(*标定文件大小*)
dwTemp :=32 ;
(*对标定参数进行写入*)
IF dwTemp <> SysFileWrite(dwFile, ADR(IO_station[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;
dwFile := SysFileOpen(str_IO_UserVarPath, 'w');
IF dwFile = 0 THEN (*读取标定文件报警*)
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
(*标定文件大小*)
dwTemp := 640;
(*对标定参数进行写入*)
IF dwTemp <> SysFileWrite(dwFile, ADR(IO_UserVar[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;
dwFile := SysFileOpen(str_IOamountPath, 'w');
IF dwFile = 0 THEN (*读取标定文件报警*)
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
(*标定文件大小*)
dwTemp := 4;
(*对标定参数进行写入*)
IF dwTemp <> SysFileWrite(dwFile, ADR(IOamount[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;
dwFile := SysFileOpen(str_IOsetPath, 'w');
IF dwFile = 0 THEN (*读取标定文件报警*)
ALARM_WRITE_PRM_FILE := TRUE;
ELSE
(*标定文件大小*)
dwTemp := 400;
(*对标定参数进行写入*)
IF dwTemp <> SysFileWrite(dwFile, ADR(IOset[1]), dwTemp) THEN
ALARM_WRITE_PRM_FILE := TRUE;
END_IF
SysFileClose(dwFile);
END_IF
dwFile := 0;