CoDeSys+n   Example_DL1.0 vom 4.10.2004A. Schiff, ICS GmbHtDas Programm ldt Texte in das An- zeigemodul AM002/AM003 und liest sie anschlieend der Reihe nach wieder aus. $ D  a ((K6KDKRKgt+yyQs/`SSerial (RS232)Lokal_3S Serial RS232 driver,PortCOM1COM8YBaudrate4800%9600K1920038400576001152004ParityNoEvenOdd3Stop bits11,527dMotorola byteorderNoYesyQs/`SSerial (RS232)Lokal_3S Serial RS232 driver,PortCOM1COM8YBaudrate4800%9600K1920038400576001152004ParityNoEvenOdd3Stop bits11,527dMotorola byteorderNoYesK>#,8T,CoDeSys 1-2.2. "$ '(P~@@@@@@MNOP`atyzbcde_Q\RUXZ  "!#$^fghijkFHJLNPRUSTVlopqrsuuv."$ '(tyzbde\RUXZ  "!#$fghijkFHJLNPRUSTVopqrsuuv)g geettiStandard Parameter OD(%Typ des OD-Eintrags whlen. BOOL 8-bit-Integer16-bit-Integer32-bit-Integerbyteword double wordrealstringlong real (64-bit)lowmiddlehigh read only write only read-writeStandard Variable ODlowmiddlehigh read only write only read-writedl I1:ep  Module.Root-1 __not_found__Hardware configurationIBdect * E%QBOO NDAR%MB%Module.ASI_Master11 Module.Root AS-i Master 1IBdect * E%QBOO NDAR%MB% 1Module.ASI_StdSlave1Module.ASI_Master1 Single SlaveIBct * E%QB NDAR%MB%aDI0Input D0Channel.ASIBitInput1Module.ASI_StdSlaveIX * E%aDI1Input D1Channel.ASIBitInput2Module.ASI_StdSlaveIX * E%aDI2Input D2Channel.ASIBitInput3Module.ASI_StdSlaveIX * E%aDI3Input D3Channel.ASIBitInput4Module.ASI_StdSlaveIX * E%aDO0 Output D0Channel.ASIBitOutput5Module.ASI_StdSlaveQXNDAR%aDO1 Output D1Channel.ASIBitOutput6Module.ASI_StdSlaveQXNDAR%aDO2 Output D2Channel.ASIBitOutput7Module.ASI_StdSlaveQXNDAR%aDO3 Output D3Channel.ASIBitOutput8Module.ASI_StdSlaveQXNDAR% 5Module.ASI_StdSlave1Module.ASI_Master1 Single SlaveIBct * E%QB NDAR%MB%aDI0Input D0Channel.ASIBitInput1Module.ASI_StdSlaveIX * E%aDI1Input D1Channel.ASIBitInput2Module.ASI_StdSlaveIX * E%aDI2Input D2Channel.ASIBitInput3Module.ASI_StdSlaveIX * E%aDI3Input D3Channel.ASIBitInput4Module.ASI_StdSlaveIX * E%aDO0 Output D0Channel.ASIBitOutput5Module.ASI_StdSlaveQXNDAR%aDO1 Output D1Channel.ASIBitOutput6Module.ASI_StdSlaveQXNDAR%aDO2 Output D2Channel.ASIBitOutput7Module.ASI_StdSlaveQXNDAR%aDO3 Output D3Channel.ASIBitOutput8Module.ASI_StdSlaveQXNDAR% 30Module.ASI_StdSlave1Module.ASI_Master1 Single SlaveIBct * E%QB NDAR%MB%aDI0Input D0Channel.ASIBitInput1Module.ASI_StdSlaveIX * E%aDI1Input D1Channel.ASIBitInput2Module.ASI_StdSlaveIX * E%aDI2Input D2Channel.ASIBitInput3Module.ASI_StdSlaveIX * E%aDI3Input D3Channel.ASIBitInput4Module.ASI_StdSlaveIX * E%aDO0 Output D0Channel.ASIBitOutput5Module.ASI_StdSlaveQXNDAR%aDO1 Output D1Channel.ASIBitOutput6Module.ASI_StdSlaveQXNDAR%aDO2 Output D2Channel.ASIBitOutput7Module.ASI_StdSlaveQXNDAR%aDO3 Output D3Channel.ASIBitOutput8Module.ASI_StdSlaveQXNDAR%   31AModule.ASI_ABSlave1Module.ASI_Master1 A/B SlaveIBct * E%QB NDAR%MB%aDI0Input 0Channel.ASIBitInput1Module.ASI_ABSlaveIX * E%aDI1Input 1Channel.ASIBitInput2Module.ASI_ABSlaveIX * E%aDI2Input 2Channel.ASIBitInput3Module.ASI_ABSlaveIX * E%aDI3Input 3Channel.ASIBitInput4Module.ASI_ABSlaveIX * E%aDO0Output 0Channel.ASIBitOutput5Module.ASI_ABSlaveQXNDAR%aDO1Output 1Channel.ASIBitOutput6Module.ASI_ABSlaveQXNDAR%aDO2Output 2Channel.ASIBitOutput7Module.ASI_ABSlaveQXNDAR%   31BModule.ASI_ABSlave1Module.ASI_Master1 A/B SlaveIBct * E%QB NDAR%MB%aDI0Input 0Channel.ASIBitInput1Module.ASI_ABSlaveIX  * E%aDI1Input 1Channel.ASIBitInput2Module.ASI_ABSlaveIX  * E%aDI2Input 2Channel.ASIBitInput3Module.ASI_ABSlaveIX  * E%aDI3Input 3Channel.ASIBitInput4Module.ASI_ABSlaveIX  * E%aDO0Output 0Channel.ASIBitOutput5Module.ASI_ABSlaveQX NDAR%aDO1Output 1Channel.ASIBitOutput6Module.ASI_ABSlaveQX NDAR%aDO2Output 2Channel.ASIBitOutput7Module.ASI_ABSlaveQX NDAR%> # DxVAR_GLOBAL END_VAR X# =j"`>$ALonStandard> > ND :"?\VAR_CONFIG END_VAR ',BB\Globale_Variablen> B?esVaabs  VAR_GLOBAL ASI1_AUTO_ADDRESS, ASI1_AUTO_ADDRESS_POSSIBLE, ASI1_CONFIG_OK: BOOL; ASI1_NORMAL, ASI1_OFFLINE, ASI1_POWER_FAIL: BOOL; ASI1_PROJECTION_MODE, ASI1_SLAVE0_EXIST, ASI1_PERIPHERY_OK: BOOL; ASI1_AUTO_ADDRESS_ENABLE, ASI1_DATA_EXCHANGE_ACTIVE: BOOL; ASI2_AUTO_ADDRESS, ASI2_AUTO_ADDRESS_POSSIBLE, ASI2_CONFIG_OK: BOOL; ASI2_NORMAL, ASI2_OFFLINE, ASI2_POWER_FAIL: BOOL; ASI2_PROJECTION_MODE, ASI2_SLAVE0_EXIST, ASI2_PERIPHERY_OK: BOOL; ASI2_AUTO_ADDRESS_ENABLE, ASI2_DATA_EXCHANGE_ACTIVE: BOOL; END_VAR < it&gphGlobale'XX;Variablen_Konfiguration> >futi, t VAR_CONFIG END_VAR D_VAR VAR_OUTPUT Q1: BOOL; END_VAR ,xtCodeVar2ѧ? ?TFUNCTION_BLOCK CodeVar2 (* Dieser Funktionsblock codiert eine String-Variable mit Ausgabetext um in ein Datenfeld. Gleichzeitig knnen eine oder zwei Variablen in den Text eingefgt werden. Die Positionen und Formatierungen der Variablen werden durch den Platzhalter '&' gekennzeichnet. Beispiele: INT=1 und Formatierung: &&&,& ergibt: ' 0,1' INT=-1 und Formatierung: &&,&& ergibt: '-0,01' INT=99 und Formatierung: &&& ergibt: ' 99' Bei berlauf wird keine Konvertierung vorgenommen. Grte darstellbare Zahl: 9999, kleinste: -999 grte negative Zahl: -0,01 Achtung: Das Zeichen $ darf im Text nicht vorkommen! *) VAR_INPUT Text: STRING(16); (* Unterlegter Text; &&,& wird belegt mit Variablen-Werten *) Var1:INT; (* Variable 1, wird entsprechend Vorgabe durch && umcodiert *) Var2:INT; (* Variable 2, wird entsprechend Vorgabe durch && umcodiert *) Var3:INT; (* Variable 3, wird entsprechend Vorgabe durch && umcodiert *) END_VAR VAR_OUTPUT Feld: ARRAY[0..15] OF BYTE; END_VAR VAR i: BYTE; pByteArray: POINTER TO ARRAY [0..16] OF BYTE; Zahl1: INT; Zahl2: INT; Zahl3: INT; Zahl4: INT; ZahlN: INT; Variable:INT; Zeichen1: BYTE; Zeichen2: BYTE; Zeichen3: BYTE; Zeichen4: BYTE; j: BYTE; k: BYTE; k2: BYTE; k1: BYTE; k3: BYTE; Komma: BYTE; Error: BOOL; k4: BYTE; END_VARz pByteArray:=ADR(Text); FOR i:=0 TO 15 DO Feld[i]:=pByteArray^[i]; (* , , , , und umcodieren *) IF Feld[i]=16#E4 THEN Feld[i]:=16#E1; END_IF; (* *) IF Feld[i]=16#F6 THEN Feld[i]:=16#EF; END_IF; (* *) IF Feld[i]=16#FC THEN Feld[i]:=16#F5; END_IF; (* *) IF Feld[i]=16#DF THEN Feld[i]:=16#E2; END_IF; (* *) IF Feld[i]=16#B0 THEN Feld[i]:=16#DF; END_IF; (* *) IF Feld[i]=16#B5 THEN Feld[i]:=16#E4; END_IF; (* *) IF Feld[i]=16#A7 THEN Feld[i]:=16#F4; END_IF; (* Ohm *) END_FOR; (* Eintragen der Variablen *) Variable:=Var1; FOR k:=1 TO 3 DO IF Variable<=9999 AND Variable>=-999 THEN IF Variable>=0 THEN (* positiver Zahlenbereich zwischen 0 und +9999 *) Zahl1:=Variable/1000; Zahl2:=Variable/100-Zahl1*10; Zahl3:=Variable/10-Zahl1*100-Zahl2*10; Zahl4:=Variable -Zahl1*1000-Zahl2*100-Zahl3*10; Zeichen1:=INT_TO_BYTE(Zahl1)+48; Zeichen2:=INT_TO_BYTE(Zahl2)+48; Zeichen3:=INT_TO_BYTE(Zahl3)+48; Zeichen4:=INT_TO_BYTE(Zahl4)+48; ELSE (* negativer Zahlenbereich zwischen -999 und -0,01 *) ZahlN:=-Variable; Zahl2:=ZahlN/100; Zahl3:=ZahlN/10-Zahl2*10; Zahl4:=ZahlN-Zahl2*100-Zahl3*10; Zeichen1:=16#2D; Zeichen2:=INT_TO_BYTE(Zahl2)+48; Zeichen3:=INT_TO_BYTE(Zahl3)+48; Zeichen4:=INT_TO_BYTE(Zahl4)+48; END_IF; ELSE Zeichen1:=16#23; Zeichen2:=16#23; Zeichen3:=16#23; Zeichen4:=16#23; END_IF; (* Suchen der Stelle, an der die Zahl eingetragen werden soll *) Komma:=0; FOR i:=0 TO 15 DO IF Feld[i]=16#26 THEN k1:=i; (* Position Feldanfang *) Feld[i]:=16#23; FOR j:=1 TO 5 DO IF Feld[i+j]=16#2C OR Feld[i+j]=16#2E THEN Komma:=i+j; (* Position Komma oder Punkt*) k4:=Feld[i+j]; (* Punkt oder Komma *) END_IF; IF Feld[i+j]=16#26 THEN Feld[i+j]:=16#23; END_IF; IF Feld[i+j]<>16#23 AND Feld[i+j]<>k4 THEN k2:=i+j-1; (* Position Feldende *) k3:=Feld[k2+1]; (* Zeichen hinter Feldende *) j:=5; END_IF; END_FOR; i:=15; END_IF; END_FOR; (* Prfung, ob kein berlauf oder sonstiger Konflikt bei Darstellung *) Error:=FALSE; (* entfllt *) (* Eintragen der Zeichen *) IF Error=FALSE THEN IF k2>=k1 AND Feld[k2]=16#23 THEN Feld[k2]:=Zeichen4; k2:=k2-1; END_IF; IF Feld[k2]=k4 THEN k2:=k2-1; END_IF; IF k2>=k1 AND Feld[k2]=16#23 THEN Feld[k2]:=Zeichen3; k2:=k2-1; END_IF; IF Feld[k2]=k4 THEN k2:=k2-1; END_IF; IF k2>=k1 AND Feld[k2]=16#23 THEN Feld[k2]:=Zeichen2; k2:=k2-1; END_IF; IF Feld[k2]=k4 THEN k2:=k2-1; END_IF; IF k2>=k1 AND Feld[k2]=16#23 THEN Feld[k2]:=Zeichen1; k2:=k2-1; END_IF; (* Fhrende Nullen unterdrcken, Minuszeichen ggf. verschieben *) IF Feld[k1]=16#30 AND Feld[k1+1]<>k4 AND Feld[k1+1]<>k3 THEN Feld[k1]:=16#20; END_IF; IF Feld[k1]=16#20 AND Feld[k1+1]=16#30 AND Feld[k1+2]<>k4 AND Feld[k1+2]<>k3 THEN Feld[k1+1]:=16#20; END_IF; IF Feld[k1+1]=16#20 AND Feld[k1+2]=16#30 AND Feld[k1+3]<>k4 AND Feld[k1+3]<>k3 THEN Feld[k1+2]:=16#20; END_IF; IF Feld[k1]=16#2D AND Feld[k1+1]=16#30 AND Feld[k1+2]<>k4 AND Feld[k1+2]<>k3 THEN Feld[k1]:=16#20; Feld[k1+1]:=16#2D; END_IF; IF Feld[k1+1]=16#2D AND Feld[k1+2]=16#30 AND Feld[k1+3]<>k4 THEN Feld[k1+1]:=16#20; Feld[k1+2]:=16#2D; END_IF; END_IF; IF k=1 THEN Variable:=Var2; ELSE Variable:=Var3; END_IF; END_FOR;%,BPLC_PRG|nA UnA (PROGRAM PLC_PRG (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) (* Anzeige-Text-Ladeprogramm mit Auslesefunktion *) (* *) (* ICS GmbH, Hopfenstrae 1, 88069 Tettnang, Autor: Andreas Schiff Version 1.0 Datum: 4.10.04 *) (* *) (* Dieses Beispielprogramm dient nur zur Demonstration der Funktion des AM002/3. Es kann keine Gewhr dafr *) (* bernommen werden, dass dieses Programm in einem realen Automatisierungsprojekt fehlerfrei luft. *) (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) VAR DI2 AT %IX1.5.2:BOOL; (* Datenports fr serielle Kommunikation *) DI3 AT %IX1.5.3:BOOL; (* Slave ist auf Adresse 5 *) DO0 AT %QX1.5.0: BOOL; DO1 AT %QX1.5.1:BOOL; Version: BYTE:=10; (* Programm- und Versionsnummer des Programms *) ZNr: BYTE; Text1: BYTE; Text2: BYTE; Texx: ARRAY [5..127] OF STRING:= 'Dies ist Text1..', (* Hier werden die Soll-Texte der Reihe nach eingetragen *) '..und dies Text2', 'www.ICS-GmbH.com', '++++++++++++++++'; AnzB1: ARRAY [0..15] OF BYTE; (* erste Zeile Anzeigemodul (Slaveadresse 4) *) AnzB2: ARRAY [0..15] OF BYTE; (* zweite Zeile Anzeigemodul *) AnzeigeB: SerComA; Initial:BOOL:=TRUE; StepNr:BYTE; Warten:WORD; Taktgeber1:TON; Taktgeber2:TON; HB1:BOOL; Takt1:BOOL; Taktgeber3:TON; Taktgeber4:TON; HB2:BOOL; Takt2:BOOL; Textvar2:CodeVar2; ZeilNr: BYTE; ZMax: BYTE; Z2Nr: BYTE; i: BYTE; END_VAR (* Ende des Deklarationsteils *)(* Takt2: 500ms *) Taktgeber3(IN:=Takt2,PT:=t#250ms); HB2:=NOT Taktgeber3.Q; Taktgeber4(IN:=HB2,PT:=t#250ms); Takt2:=Taktgeber4.Q; AnzeigeB(DI2:=DI2, Di3:=Di3, DatIn1:=AnzB1, DatIn2:=AnzB2, Zeile1:=ZNr, Zeile2:=Z2Nr, TextNr1:=Text1, TextNr2:=Text2); DO0:=AnzeigeB.DO0; DO1:=AnzeigeB.DO1; (* --------------------------------------------------------- Initialisieren ---------------------------------------------------------------------- *) (* Initialisieren beim Zuschalten der Betriebsspannung *) IF Initial=TRUE THEN IF StepNr=0 THEN TextVar2(Text:='Ladeprogramm &.&',Var1:=Version); AnzB1:=TextVar2.Feld; TextVar2(Text:='lade Texte .. ..'); AnzB2:=TextVar2.Feld; Text1:=0; Text2:=0; ZNr:=3; Z2Nr:=4; StepNr:=1; Warten:=0; END_IF; IF StepNr=1 THEN Warten:=Warten+1; IF Warten>6000 THEN ZNr:=0; i:=4; Z2Nr:=0; Warten:=0; StepNr:=StepNr+1; END_IF; END_IF; IF StepNr=2 THEN Warten:=Warten+1; IF Warten>1500 OR (AnzeigeB.Diagnosis=0) THEN i:=i+1; TextVar2(Text:=Texx[i]); AnzB1:=TextVar2.Feld; ZNr:=i; Warten:=0; StepNr:=StepNr+1; END_IF; END_IF; IF StepNr=3 THEN IF Texx[ZNr]='++++++++++++++++' THEN ZMax:=ZNr; Warten:=Warten+1; IF Warten>2000 THEN Initial:=FALSE; ZeilNr:=5; ZNr:=0; END_IF; ELSE StepNr:=2; END_IF; END_IF; ELSE (* --------------------------------------------------------------- Hauptprogramm ---------------------------------------------------------------- *) (* Hier werden alle geladenen Texte der Reihe nach angezeigt *) Warten:=Warten+1; IF Warten>1000 THEN ZNr:=0; END_IF; IF Warten>1600 THEN TextVar2(Text:='Text Nr. &&&: ',Var1:=ZeilNr); AnzB1:=TextVar2.Feld; ZNr:=3; Text1:=3; Text2:=ZeilNr; ZeilNr:=ZeilNr+1; IF ZeilNr>ZMax THEN ZeilNr:=5; END_IF; Warten:=0; END_IF; END_IF; a,(SerComAnA nA@ FUNCTION_BLOCK SerComA (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) (* Dieser Funktionsbaustein wickelt die gesamte serielle Kommunikation zu einem AS-Interface Slave nach dem *) (* Profil S-B.A.5 ab. Gilt nur fr 2zeilige Ausgabe! *) (* *) (* ICS GmbH, Hopfenstrae 1, 88069 Tettnang, Autor: Andreas Schiff Version 0.1 Datum: 4.12.03 *) (* *) (* ------------------------------------------------------------------------------------------------------------------------------------------------------- *) VAR_INPUT DI2: BOOL; DI3: BOOL; DatIn1: ARRAY [0..15] OF BYTE; (* Parameter-Solldaten Zeile 1 *) DatIn2: ARRAY [0..15] OF BYTE; (* Parameter-Solldaten Zeile 2 *) Zeile1: BYTE; (* Zeilennummer frs Schreiben bzw. Zeile 1 *) Zeile2: BYTE; (* Zeilennummer fr Zeile 2 *) TextNr1: BYTE; (* Zeilennummer 1 frs Ausgeben *) TextNr2: BYTE; (* Zeilennummer 2 frs Ausgeben *) END_VAR VAR_OUTPUT Diagnosis: BYTE; (* Diagnose-Daten: Bit 7: Slave nicht im seriellen Modus Bit 6: ID nicht korrekt Bit 5: --- Bit 4 Slave busy Bit 0..3: Diagnoseinfo vom Slave *) ID_Data: ARRAY [0..15] OF BYTE; (* ID-Daten des Slaves *) DO0: BOOL; DO1: BOOL; END_VAR VAR InputD: ARRAY [0..20] OF BYTE; (* Eingabe-Datenfeld *) InputData: ARRAY [0..20] OF BYTE; (* Eingabe-Datenfeld *) OutputData: ARRAY [0..20] OF BYTE; (* Ausgabe-Datenfeld *) OutputLen: BYTE; (* Lnge der Ausgabedaten in Byte; Zahlenbereich 1..15 *) InputL: BYTE; (* Lnge der Eingabedaten in Byte; Zahlenbereich 1..15 *) InputLen: BYTE; Taktalt: BOOL; In: BYTE; (* aktuell empfangene Nachricht *) Inalt: BYTE; (* letzte empfangene Nachricht *) Out: BYTE:= 3; Parameter: BYTE:=1; Watchdog: BOOL; Timeout: BYTE; Lastin: BYTE; (* letztes gltiges empfangenes Informationsbit *) i: BYTE; IBitzeiger: BYTE; Outalt: BYTE; Outzeiger: BYTE; OBitzeiger: BYTE; x: BYTE; Send: BOOL; y: BYTE; Outx: BYTE; Inx: BYTE; NewData: BOOL; SCSlave: BOOL; SSW: WORD; Inst1:TON; Inst2:TON; Takt:BOOL; Var2: BOOL; Acyclic: WORD; Para_Data: ARRAY [0..20] OF BYTE; Para_Data2: ARRAY [0..20] OF BYTE; Toggle: BYTE; Timeout2: BYTE; MerkDat1: BOOL; MerkDat2: BOOL; Text1alt: BYTE; Text2alt: BYTE; Zeile1alt: BYTE; Zeile2alt: BYTE; END_VAR (* ----------------------------------------------Ende des Deklarationsteils------------------------------------------------------- *)(* Hier wird ein Takt mit einer Zykluszeit von 20ms generiert *) Inst1(IN:=Takt, PT:=t#10ms); Var2:=NOT Inst1.Q; Inst2(IN:=Var2, PT:=t#10ms); Takt:=Inst2.Q; (* Eingnge des Slaves lesen, ausmaskieren und auf Vernderung prfen *) IF DI2=FALSE AND DI3=FALSE THEN In:=0; END_IF; IF DI2=FALSE AND DI3=TRUE THEN In:=2; END_IF; IF DI2=TRUE AND DI3=FALSE THEN In:=1; END_IF; IF DI2=TRUE AND DI3=TRUE THEN In:=3; END_IF; IF In<>Inalt THEN (* eine Antwort ist eingetroffen *) IF Out=1 AND In=1 THEN (* die eine der erwarteten Antworten ist eingetroffen: Separator *) Watchdog:=FALSE; SCSlave:=TRUE; Timeout:=0; Lastin:=Inalt; (* Aktion 2: Trenn-Nachricht empfangen; Master sendet Information oder Idle *) IF Send=TRUE THEN IF Outalt=3 THEN (* Ausgabe initialisieren *) Outzeiger:=0; OBitzeiger:=0; y:=OutputData[0]; END_IF; Outalt:=Out; x:=y AND 2#1000_0000; IF x<>0 THEN Out:=2; ELSE Out:=0; END_IF; y:=SHL (y,1); OBitzeiger:=OBitzeiger+1; (* ein Byte fertig? Zeiger auf nchstes Byte stellen *) IF OBitzeiger>7 THEN Outzeiger:=Outzeiger+1; y:=OutputData[Outzeiger]; OBitzeiger:=0; IF Outzeiger>=OutputLen OR Outzeiger>=19 THEN Send:=FALSE; SCSlave:=TRUE; END_IF; END_IF; ELSE Outalt:=Out; Out:=3; END_IF; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; ELSIF Out<>1 AND In<>1 THEN (* die andere der erwarteten Antworten ist eingetroffen: Idle oder Daten *) Watchdog:=FALSE; SCSlave:=TRUE; Timeout:=0; IF (In=0 AND Inalt<>2) OR (In=2 AND Inalt<>0) THEN (* Aktion 0/1: Slave hat Informationsbit gesendet: abspeichern; Master sendet Trenn-Nachricht *) IF Lastin=3 THEN (* Beginn einer Nachricht: Zeiger und Feld Initialisieren, wenn Feld bereit *) NewData:=FALSE; InputL:=0; IBitzeiger:=0; FOR i:=0 TO 19 DO InputD[i]:=0; END_FOR; END_IF; InputD[InputL]:=SHL(InputD[InputL],1); IF In=2 THEN InputD[InputL]:=InputD[InputL]+1; END_IF; IBitzeiger:=IBitzeiger+1; IF IBitzeiger>7 THEN InputL:=InputL+1; IF InputL>19 THEN InputL:=19; END_IF; IBitzeiger:=0; END_IF; Outalt:=Out; Out:=1; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; ELSE (* Aktion 3: Slave hat Idle gesendet: Abschluss einer Nachricht?; Master sendet Trenn-Nachricht *) IF Lastin<>3 THEN (* Abschluss einer Nachricht; wenn diese nicht vollstndig (also ganzzahlige Anzahl von Bytes), dann wird sie verworfen! *) IF IBitzeiger =0 THEN FOR i:=0 TO InputL DO InputData[i]:=InputD[i]; END_FOR; NewData:=TRUE; InputLen:=InputL; SCSlave:=TRUE; END_IF; END_IF; Outalt:=Out; Out:=1; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; END_IF; END_IF; ELSIF (Takt<>Taktalt AND Takt=TRUE) THEN (* Slave alle 120ms testen, ob er den seriellen Kommunikationsmodus untersttzt, dient auch zum Anlauf der Kommunikation *) Timeout:=Timeout+1; IF Timeout>4 THEN Outalt:=Out; IF (Out=0 OR Out=3) THEN Out:=1; ELSIF (Out=1 OR Out=2) THEN Out:=3; END_IF; Timeout:=0; SCSlave:=FALSE; SSW:=0; Para_Data[1]:=0; Para_Data2[1]:=0; Send:=FALSE; IF Out=0 THEN DO0:=TRUE; DO1:=TRUE; END_IF; IF Out=1 THEN DO0:=FALSE; DO1:=TRUE; END_IF; IF Out=2 THEN DO0:=TRUE; DO1:=FALSE; END_IF; IF Out=3 THEN DO0:=FALSE; DO1:=FALSE; END_IF; END_IF; END_IF; (* Hier luft die Timeoutberwachung fr azyklische Dienste ab: 1s *) IF Taktalt<>Takt AND Takt=FALSE AND Acyclic<>0 THEN Timeout2:=Timeout2+1; IF Timeout2>151 THEN Acyclic:=0; Timeout2:=0; MerkDat1:=FALSE; MerkDat2:=FALSE; Diagnosis:=Diagnosis AND 16#EF; END_IF; END_IF; (* Liegt ein Kommandoaufruf vor? *) IF ID_Data[1]=0 AND Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN (* ID des Slaves abfragen *) OutputData[0]:=16; OutputData[1]:=0; OutputData[2]:=6; OutputLen:=3; Send:=TRUE; Acyclic:=100; Diagnosis:=Diagnosis OR 16#10; END_IF; (* Wenn Vernderung in Datenzeile, dann entsprechende Zeile schreiben *) IF Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN IF Zeile1>2 AND Zeile1<>Zeile1alt THEN OutputData[0]:=17; OutputData[1]:=Zeile1; OutputData[2]:=16; FOR i:=0 TO 15 DO OutputData[i+3]:=DatIn1[i]; END_FOR; OutputLen:=19; Send:=TRUE; Zeile1alt:=Zeile1; Acyclic:=103; Diagnosis:=Diagnosis OR 16#10; END_IF; END_IF; (* Wenn Vernderung in Datenzeile, dann entsprechende Zeile schreiben *) IF Acyclic=0 AND Send=FALSE AND SCSlave=TRUE THEN IF Zeile2>2 AND Zeile2<>Zeile2alt THEN OutputData[0]:=17; OutputData[1]:=Zeile2; OutputData[2]:=16; FOR i:=0 TO 15 DO OutputData[i+3]:=DatIn2[i]; END_FOR; OutputLen:=19; Send:=TRUE; Zeile2alt:=Zeile2; Acyclic:=104; Diagnosis:=Diagnosis OR 16#10; END_IF; END_IF; (* Wenn TextNr1 oder TextNr2 >4, dann cyclic Aufruf absetzen *) IF Send=FALSE AND Acyclic=0 AND SCSlave=TRUE THEN IF (TextNr1>4 OR TextNr2>4) AND (TextNr1<>Text1alt OR TextNr2<>Text2alt) THEN OutputData[0]:=1; OutputData[1]:=TextNr1; OutputData[2]:=TextNr2; OutputLen:=3; Text1alt:=TextNr1; Text2alt:=TextNr2; Send:=TRUE; END_IF; END_IF; IF Newdata=TRUE THEN (* ID-Daten sind angekommen *) IF InputData[0]=80 AND Acyclic=100 THEN FOR i:=0 TO 5 DO ID_Data[i]:=InputData[i+1]; END_FOR; NewData:=FALSE; Timeout2:=0; Acyclic:=0; IF ID_Data[1]<>1 THEN Diagnosis:=Diagnosis OR 16#40; ELSE Diagnosis:=Diagnosis AND 16#BF; END_IF; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Diagnosedaten sind angekommen *) IF InputData[0]=80 AND Acyclic=101 THEN Diagnosis:=InputData[1]; NewData:=FALSE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Parameter-Istdaten sind angekommen *) IF InputData[0]=81 AND Acyclic=102 THEN NewData:=FALSE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Acknowlede fr Zeile 1 Schreiben ist angekommen *) IF InputData[0]=81 AND Acyclic=103 THEN NewData:=FALSE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Acknowlede fr Zeile 2 Schreiben ist angekommen *) IF InputData[0]=81 AND Acyclic=104 THEN NewData:=FALSE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* Fehlerhafte Aufrufe*) IF InputData[0]=145 OR InputData[0]=144 THEN Diagnosis:=InputData[1]; NewData:=FALSE; Timeout2:=0; Acyclic:=0; Diagnosis:=Diagnosis AND 16#EF; END_IF; (* irgendein Fehler ist angekommen *) IF (InputData[0]=81 OR InputData[0]=0) AND Acyclic=0 THEN NewData:=FALSE; Diagnosis:=Diagnosis AND 16#EF; END_IF; END_IF; Taktalt:=Takt; IF Zeile1<3 THEN Zeile1alt:=Zeile1; END_IF; IF Zeile2<3 THEN Zeile2alt:=Zeile2; END_IF; Inalt:=In;,Z;W..\..\..\..\Programme\CoDeSysForAutomationAlliance\Library\ecoasi20.lib 3.7.02 15:24:32[..\..\..\..\Programme\CoDeSysForAutomationAlliance\Library\ecoasi21ps.lib 10.10.03 14:10:08STANDARD.LIB 23.10.00 15:20:56IECSFC.LIB 23.10.00 15:20:30akt_IDCode_lesenakt_IOConf_lesenakt_Parameter_lesenakt_Parameter_refreshakt_Parameter_schreibenASiCmd20EAO_8IO Input7_1Light Input_lesen$Ist_Konfigurationsdaten_projektieren LAS_lesen LDS_lesen LPF_lesen LPS_lesenOutput_schreibenOutputP7_lightproj_IDCode_lesenproj_IOConf_lesenproj_Parameter_lesenproj_Parameter_schreibenPt100_4Channel SendReceiveESlave_adressierenGlobale_Variablen address_slaveASiCmd21 Exec_ASI_CmdGet_ASi_Config Get_ASi_InputGet_ASi_OutputGet_current_parameterGet_Global_ListsGet_LASGet_LDSGet_LPFGet_LPSGet_Master_flagsGet_projected_ASi_ConfigGet_projected_parameterGet_Slave_Error_CounterPeripheral_fault Project_allRefresh_current_parameterSet_ASi_OutputSet_current_parameterSet_ModeSet_projected_parameter SetTestMode Slave_activeSlave_detectedSlave_projectedGlobale_VariablenCONCATCTDCTUCTUDDELETEF_TRIGFINDINSERTLEFTLENMIDR_TRIGREPLACERIGHTRSRTCSEMASRTOFTONTPGlobal Variables 0SFCActionControlGlobale_Variablen,XXb PLC_PRG.AnzeigeB.In PLC_PRG.AnzeigeB.out PLC_PRG.AnzeigeB.NewData PLC_PRG.AnzeigeB.outx  BausteineCodeVar2 PLC_PRG%SerComAa DatentypenVisualisierungenGlobale VariablenGlobale_VariablenVariablen_Konfigurationז