SCL:Находим МАКСИМУМ в массиве REAL
Дата: 2009-03-27
Добавлено: komatic
Тема: SCL
Функциональный блок FB (используется POINTER)
Функция FC (используется ANY)
Функциональный блок ищет максимальное значение REAL в массиве, заданном через параметр POINTER, используется отображение входного параметра с помощью AT и тестирование блока данных на присутствие в памяти контроллера.
Ничего лишнего, единственное что напрягает использование функционального блока, в котором нет необходимости. (исправленная версия во втором примере)
Исходник взят с сайта oscat.de, где, кстати, очень много полезного...
Ну и конечно, после небольших изменний, этот блок может использоваться для поиска минимального значения
MAX функциональный блок
(* @PATH := " \/mathematical\/array functions" *)
FUNCTION_BLOCK FB100
TITLE = " array_max"
//
// this function will calculate the max value of a given array.
// the function needs to be called: array_max(adr("array"),sizeof("array"));
// because this function works with pointers its very time
// efficient and it needs no extra memory.
VERSION : " 1.0"
AUTHOR : hugo
NAME : AR_MAX
FAMILY : ARFUNCT
VAR_INPUT
pt: POINTER;
at_pt AT pt: STRUCT
DBNr: WORD;
Adr: DWORD;
END_STRUCT;
size : INT;
END_VAR
VAR_OUTPUT
_max: REAL;
END_VAR
VAR_TEMP
i: INT;
Adr: INT;
DB_LENGTH: WORD;
WRITE_PROT: BOOL;
rTEST_DB: INT;
END_VAR
(*
version 1.0 2 oct 2006
programmer hugo
tested by Albinus
*)
(* Datenbaustein Testen *)
rTEST_DB := TEST_DB(DB_NUMBER := at_pt.DBNr // IN: WORD
,DB_LENGTH := DB_LENGTH // OUT: WORD
,WRITE_PROT := WRITE_PROT // OUT: BOOL
); // INT
(* Ende wenn Test-DB <> 0 = Fehler *)
IF rTEST_DB <> 0 THEN RETURN; END_IF;
(* Ende wenn DB zu klein *)
IF WORD_TO_INT(DB_LENGTH)/4 < size THEN RETURN; END_IF;
Adr := DWORD_TO_INT(SHR(IN:=SHL(IN:=at_pt.Adr,N:=8),N:=11));
(* Berechnung *)
_max := DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+0]);
FOR i := 1 TO size-1 DO
IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]) > _max THEN
_max := DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]);
END_IF;
END_FOR;
END_FUNCTION_BLOCK
MAX функция
Второй пример, находит максимальное значение REAL в массиве, заданном через параметр ANY и использует функцию, а не функциональный блок, из него убраны проверки на корректность входного параметра, для облегчения читаемости. Все таки использование функции более логично в данном случае, да и блоков данных, захламляющих программу контроллера будет меньше.
FUNCTION FC100:VOID
TITLE = " array_max"
AUTHOR : komatic
VAR_INPUT
pt: ANY;
END_VAR
VAR_OUTPUT
_max: REAL;
END_VAR
VAR_TEMP
i: INT;
Adr: DINT;
pt1: ANY;
at_pt AT
pt1: STRUCT
S7_type:BYTE;
Data_type:BYTE;
Repetition_factor:INT;
DBNr: WORD;
Adr: DWORD;
END_STRUCT;
END_VAR
pt1:=pt;
Adr := DWORD_TO_INT(SHR(IN:=SHL(IN:=at_pt.Adr,N:=8),N:=11));
_max := DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+0]);
FOR i := 1 TO at_pt.Repetition_factor-1 DO
IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]) > _max THEN
_max :=
DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]);
END_IF;
END_FOR;
END_FUNCTION
Просмотров: 8936
Комментарии к материалу
Ваш будет первым.
Добавить комментарий