FUNCTION_BLOCK "FlowMeters"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
RstCounters_ch1 : Bool;
RstCounters_ch2 : Bool;
Init : Bool;
END_VAR
VAR_INPUT RETAIN
ch1_enabled : Bool;
ch2_enabled : Bool;
END_VAR
VAR_OUTPUT
mass_flow_ch1 : Real;
mass_flow_ch2 : Real;
den_ch1 : Real;
den_ch2 : Real;
temp_ch1 : Real;
temp_ch2 : Real;
vol_flow_ch1 : Real;
vol_flow_ch2 : Real;
mass_cntr_ch1 : Real;
mass_cntr_ch2 : Real;
vol_cntr_ch1 : Real;
vol_cntr_ch2 : Real;
comm_err_ch1 : Bool;
comm_err_ch2 : Bool;
ch1_status : Int;
ch2_status : Int;
cur_mass_cntr_ch1 : Real;
cur_mass_cntr_ch2 : Real;
cur_vol_cntr_ch1 : Real;
cur_vol_cntr_ch2 : Real;
END_VAR
VAR
Comm_load {InstructionName := 'Modbus_Comm_Load'; LibVersion := '3.1'} : Modbus_Comm_Load;
Master {InstructionName := 'Modbus_Master'; LibVersion := '3.2'} : Modbus_Master;
master_done { S7_SetPoint := 'True'} : Bool;
master_busy : Bool;
Master_error : Bool;
Master_error_code : Word;
error_code_ch1 : Word;
error_code_ch2 : Word;
ControlVar : Int;
Send_P2P_Instance {InstructionName := 'Send_P2P'; LibVersion := '3.1'} : Send_P2P;
END_VAR
VAR_TEMP
i : Int;
END_VAR
VAR CONSTANT
log_1 : Word := 16#FF00;
END_VAR
BEGIN
IF #Init THEN
//Зануляем управляющий счётчик
#ControlVar := 0;
//Зануляем выходные переменные блока
#mass_flow_ch1 := 0;
#mass_flow_ch2 := 0;
#den_ch1 := 0;
#den_ch2 := 0;
#temp_ch1 := 0;
#temp_ch2 := 0;
#vol_flow_ch1 := 0;
#vol_flow_ch2 := 0;
#mass_cntr_ch1 := 0;
#mass_cntr_ch2 := 0;
#vol_cntr_ch1 := 0;
#vol_cntr_ch2 := 0;
#cur_mass_cntr_ch1 := 0;
#cur_mass_cntr_ch2 := 0;
#cur_vol_cntr_ch1 := 0;
#cur_vol_cntr_ch2 := 0;
#comm_err_ch1 := FALSE;
#comm_err_ch2 := FALSE;
"FlowMeters_data".rst.b01 := TRUE;
//Устанавливаем режим работы порта
#Comm_load.MODE := 4;
FILL_BLK(IN := 16#0,
COUNT := 8,
OUT => "FlowMeters_data".WriteBuf[0]);
FILL_BLK(IN := 16#0,
COUNT := 12,
OUT => "FlowMeters_data".ReadBuf[0]);
END_IF;
//Инит порта
#Comm_load(REQ := #Init,
"PORT" := "Local~8B1_5",
BAUD := 9600,
PARITY := 0,
MB_DB := #Master.MB_DB);
//Основной конечный автомат
CASE #ControlVar OF
//0 - канал 1 проверка флага обнуления
0:
IF (NOT #ch1_enabled AND #RstCounters_ch1) THEN
#Master(REQ := true,
MB_ADDR := 1,
MODE := 1,
DATA_ADDR := 0004,
DATA_LEN := 1,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := "FlowMeters_data".rst);
ELSE
#ControlVar := 1;
END_IF;
//1 канал 2 проверка флага обнуления
1:
IF (NOT #ch2_enabled AND #RstCounters_ch2) THEN
#Master(REQ := true,
MB_ADDR := 2,
MODE := 1,
DATA_ADDR := 0004,
DATA_LEN := 1,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := "FlowMeters_data".rst);
ELSE
#ControlVar := 2;
END_IF;
2:
IF #ch1_enabled THEN
//Читаем данные со счётчика №1
#Master(REQ := TRUE,
MB_ADDR := 1,
MODE := 0,
DATA_ADDR := 400168,
DATA_LEN := 12,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := P#DB6.DBX16.0 WORD 12);
ELSE
#ControlVar := 3;
END_IF;
3:
IF #ch2_enabled THEN
//Читаем данные со счётчика №2
#Master(REQ := TRUE,
MB_ADDR := 2,
MODE := 0,
DATA_ADDR := 400168,
DATA_LEN := 12,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := P#DB6.DBX16.0 WORD 12);
ELSE
#ControlVar := 4;
END_IF;
4:
IF #ch1_enabled THEN
#Master(REQ := TRUE,
MB_ADDR := 1,
MODE := 0,
DATA_ADDR := 400259,
DATA_LEN := 8,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := P#DB6.DBX16.0 WORD 8);
ELSE
#ControlVar := 5;
END_IF;
5:
IF #ch2_enabled THEN
#Master(REQ := TRUE,
MB_ADDR := 2,
MODE := 0,
DATA_ADDR := 400259,
DATA_LEN := 8,
DONE => #master_done,
BUSY => #master_busy,
ERROR => #Master_error,
STATUS => #Master_error_code,
DATA_PTR := P#DB6.DBX16.0 WORD 8);
ELSE
#ControlVar := 0;
END_IF;
END_CASE;
IF #master_done THEN
CASE #ControlVar OF
0:
#comm_err_ch1 := false;
#error_code_ch1 := 0;
1:
#comm_err_ch2 := false;
#error_code_ch2 := 0;
2:
#mass_flow_ch1 := "FlowMeters_data".ReadBuf[0];
#den_ch1 := "FlowMeters_data".ReadBuf[1];
#temp_ch1 := "FlowMeters_data".ReadBuf[2];
#vol_flow_ch1 := "FlowMeters_data".ReadBuf[3];
#mass_cntr_ch1 := "FlowMeters_data".ReadBuf[4];
#vol_cntr_ch1 := "FlowMeters_data".ReadBuf[5];
#comm_err_ch1 := false;
#error_code_ch1 := 0;
3:
#mass_flow_ch2 := "FlowMeters_data".ReadBuf[0];
#den_ch2 := "FlowMeters_data".ReadBuf[1];
#temp_ch2 := "FlowMeters_data".ReadBuf[2];
#vol_flow_ch2 := "FlowMeters_data".ReadBuf[3];
#mass_cntr_ch2 := "FlowMeters_data".ReadBuf[4];
#vol_cntr_ch2 := "FlowMeters_data".ReadBuf[5];
#comm_err_ch2 := false;
#error_code_ch2 := 0;
4:
#cur_mass_cntr_ch1 := "FlowMeters_data".ReadBuf[2];
#cur_vol_cntr_ch1 := "FlowMeters_data".ReadBuf[3];
#comm_err_ch1 := false;
#error_code_ch1 := 0;
5:
#cur_mass_cntr_ch2 := "FlowMeters_data".ReadBuf[2];
#cur_vol_cntr_ch2 := "FlowMeters_data".ReadBuf[3];
#comm_err_ch2 := false;
#error_code_ch2 := 0;
END_CASE;
END_IF;
IF NOT #ch1_enabled THEN
#mass_flow_ch1 := -1;
#den_ch1 := -1;
#temp_ch1 := -1;
#vol_flow_ch1 := -1;
#mass_cntr_ch1 := -1;
#vol_cntr_ch1 := -1;
#comm_err_ch1 := false;
#error_code_ch1 := 0;
#cur_mass_cntr_ch1 := -1;
#cur_vol_cntr_ch1 := -1;
END_IF;
IF NOT #ch2_enabled THEN
#mass_flow_ch2 := -1;
#den_ch2 := -1;
#temp_ch2 := -1;
#vol_flow_ch2 := -1;
#mass_cntr_ch2 := -1;
#vol_cntr_ch2 := -1;
#comm_err_ch2 := false;
#error_code_ch2 := 0;
#cur_mass_cntr_ch2 := -1;
#cur_vol_cntr_ch2 := -1;
END_IF;
IF #Master_error THEN
IF #ControlVar = 0 OR #ControlVar = 2 OR #ControlVar = 4 THEN
#comm_err_ch1 := true;
#error_code_ch1 := #Master_error_code;
END_IF;
IF #ControlVar = 1 OR #ControlVar = 3 OR #ControlVar = 5 THEN
#comm_err_ch2 := true;
#error_code_ch2 := #Master_error_code;
END_IF;
END_IF;
IF #master_done OR #Master_error THEN
IF #ControlVar < 5 THEN
#ControlVar := #ControlVar + 1;
ELSE
#ControlVar := 0;
END_IF;
#master_done := false;
#Master_error := false;
END_IF;
#ch1_status := 0;
IF NOT #ch1_enabled THEN
#ch1_status := 2;
END_IF;
IF #comm_err_ch1 THEN
#ch1_status := 1;
END_IF;
#ch2_status := 0;
IF NOT #ch2_enabled THEN
#ch2_status := 2;
END_IF;
IF #comm_err_ch2 THEN
#ch2_status := 1;
END_IF;
END_FUNCTION_BLOCK