Пример оптимизации кода или как быстро проверить на правильность 8 BCD чисел.

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

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

optimization

 

Проверять BCD имеет смысл всегда, так как в случае неправильного числа при преобразовании его в формат INT командой BTI контроллер получит программную ошибку, попытается вызвать OB121 и в случае отсутствия этого организационного блока перейдет в режим STOP, что обычно является нежелательным поведением ).
В контроллере BCD числа часто используются при работе с датами и временем, функция чтения даты времени контроллера возвращает данные в BCD формате.

Способ был найден в Standard Library -&gt, IEC Function Blocks -&gt, FC8 (DT_TOD), который выполняет преобразование из формата DATE_AND_TIME в формат TIME_OF_DAY, автор Siemens.

Немного теории – BCD число занимает четыре бита, и является валидным если оно не больше 9

Самый простой способ проверки – использвать 8 компараторов, которые совместно с операторами сдвига сгенерируют довольно много кода как показано ниже.

 

      L     B [AR1,P#0.0],
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#0.0],
SLW   4,
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#1.0],
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#1.0],
SLW   4,
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#2.0],
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#2.0],
SLW   4,
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#3.0],
SRW   4,
L     9,
&gt,I    ,
JC    fehl,
L     B [AR1,P#3.0],
SLW   4,
SRW   4,
L     9,
&gt,I    ,
JC    fehl,

fehl: NOP   0, // ERROR

Оптимизация кода от Siemens использует тот факт, что если старший бит в тетраде (3 бит если счтить с нуля) установлен – то 2 и/или 1 бит не могут быть равны единице иначе число будет больше 9ти в любом случае.

результирующий код выглядит следующим образом.

 

L     D [AR1,P#3.0],
T     #l_z_sp,
AD    DW#16#66666666,         // sind die Bits 1 oder 2 der Tetrade gesetzt?
PUSH  ,
JZ    next,                   // wenn Bit 1 und 2 nicht gesetzt dann kein Fehler mцglich
SLD   1,                      // es kann als Ergebnis des Bit 1 und/oder 2 gesetzt sein
L     #l_z_sp,
AD    ,                       // Ergebnismaske links schieben um herauszufinden ob das Bit
AD    DW#16#88888888,         // zusдtzlich gesetzt ist
JN    fehl,                   // wenn ja, dann Fehler
TAK   ,                       // Maske aus Verundung 66666666 zurьckholen
AD    DW#16#44444444,
SLD   1,                      // Ergebnismaske schieben um herauszufinden ob Bit 3 gesetzt ist
L     #l_z_sp,
AD    ,                       // ist das Bit 3 auch gesetzt
JN    fehl,                   // wenn ja, dann Fehler
next: NOP   0,                      // letztes Nibble prьfen
fehl: NOP   0,

opt
Результаты – размер кода приблизительно в половину меньше.

Аналог в SCL, выглядит чуть понятнее )

FUNCTION FC400 : VOID

VAR_TEMP
    BCDs : DWORD,
    Error : BOOL,
END_VAR

   IF    (BCDs AND SHL(IN:=BCDs,N:=1) AND DW#16#88888888) &lt,&gt, 0 THEN
Error:=true,
ELSIF (BCDs AND SHL(IN:=BCDs,N:=2) AND DW#16#88888888) &lt,&gt, 0 THEN
Error:=true,
   END_IF,

END_FUNCTION

 

Результат компиляции

      L     #BCDs,
SLD   1,
L     #BCDs,
AD    ,
L     DW#16#88888888,
AD    ,
L     DW#16#0,
&lt,&gt,D   ,
JCN   A7d0,
SET   ,
=     #Error,
JU    A7d2,
A7d0: L     #BCDs,
SLD   2,
L     #BCDs,
AD    ,
L     DW#16#88888888,
AD    ,
L     DW#16#0,
&lt,&gt,D   ,
JCN   A7d2,
SET   ,
      =     #Error,
A7d2: CLR   ,

0 0 голоса

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

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