SCL:Находим МАКСИМУМ в массиве REAL

По просьбе наших посетителей, данный материал перенесен с сайта plc4good.org.ua, в связи с полной его потерей. Всё возражения принимаются через форму обратной связи.

plc4good.org.ua/view_post.php?id=45

max

Функциональный блок 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 &lt,&gt, 0 = Fehler *)
IF rTEST_DB &lt,&gt, 0 THEN RETURN, END_IF,
(* Ende wenn DB zu klein *)
IF WORD_TO_INT(DB_LENGTH)/4 &lt, 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 size1 DO
    IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]) &gt, _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_factor1 DO
    IF DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]) &gt, _max THEN
        _max :=
DWORD_TO_REAL(WORD_TO_BLOCK_DB(at_pt.DBNr).DD[Adr+i*4]),
    END_IF,
END_FOR,                 
END_FUNCTION

 

0 0 голоса

Оцените статью!

guest
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии