По просьбе наших посетителей, данный материал перенесен с сайта plc4good.org.ua, в связи с полной его потерей. Всё возражения принимаются через форму обратной связи.
plc4good.org.ua/view_post.php?id=45
Функциональный блок 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
Оцените статью!