Версия для печати

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

Дата: 2009-03-27

Добавлено: komatic

Тема: SCL



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 <> 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





Просмотров: 8541

Комментарии к материалу

Ваш будет первым.

Добавить комментарий

Ваше имя:

Текст комментария (4000 max):

Введите сумму с картинки: