По просьбе наших посетителей, данный материал перенесен с сайта plc4good.org.ua, в связи с полной его потерей. Всё возражения принимаются через форму обратной связи.
plc4good.org.ua/view_post.php?id=286
Проверять BCD имеет смысл всегда, так как в случае неправильного числа при преобразовании его в формат INT командой BTI контроллер получит программную ошибку, попытается вызвать OB121 и в случае отсутствия этого организационного блока перейдет в режим STOP, что обычно является нежелательным поведением ).
В контроллере BCD числа часто используются при работе с датами и временем, функция чтения даты времени контроллера возвращает данные в BCD формате.
Способ был найден в Standard Library ->, IEC Function Blocks ->, FC8 (DT_TOD), который выполняет преобразование из формата DATE_AND_TIME в формат TIME_OF_DAY, автор Siemens.
Немного теории – BCD число занимает четыре бита, и является валидным если оно не больше 9
Самый простой способ проверки – использвать 8 компараторов, которые совместно с операторами сдвига сгенерируют довольно много кода как показано ниже.
L B [AR1,P#0.0],
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#0.0],
SLW 4,
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#1.0],
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#1.0],
SLW 4,
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#2.0],
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#2.0],
SLW 4,
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#3.0],
SRW 4,
L 9,
>,I ,
JC fehl,
L B [AR1,P#3.0],
SLW 4,
SRW 4,
L 9,
>,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,
Результаты – размер кода приблизительно в половину меньше.
Аналог в SCL, выглядит чуть понятнее )
FUNCTION FC400 : VOID
VAR_TEMP
BCDs : DWORD,
Error : BOOL,
END_VARIF (BCDs AND SHL(IN:=BCDs,N:=1) AND DW#16#88888888) <,>, 0 THEN
Error:=true,
ELSIF (BCDs AND SHL(IN:=BCDs,N:=2) AND DW#16#88888888) <,>, 0 THEN
Error:=true,
END_IF,END_FUNCTION
Результат компиляции
L #BCDs,
SLD 1,
L #BCDs,
AD ,
L DW#16#88888888,
AD ,
L DW#16#0,
<,>,D ,
JCN A7d0,
SET ,
= #Error,
JU A7d2,
A7d0: L #BCDs,
SLD 2,
L #BCDs,
AD ,
L DW#16#88888888,
AD ,
L DW#16#0,
<,>,D ,
JCN A7d2,
SET ,
= #Error,
A7d2: CLR ,
Оцените статью!