//============================================================================= //SIEMENS AG //(c)Copyright 2017 All Rights Reserved //----------------------------------------------------------------------------- // Library: DriveLib // Tested with: S7-1516-3 PN/DP V1.8 // Engineering: TIA Portal V14 // Restrictions: - // Requirements: S7-1200 / S7-1500 // Functionality: read and write up to 15 parameter from/to a Sinamics // //============================================================================= // Auftrag "Parameter lesen" bzw. Auftrag "Parameter schreiben" wird nicht mehr ausgefuhrt IF NOT #sbBusy THEN // Uberprufung der auf korrekte Parametrierung der Anzahl der Parameter IF #ParaNo > #siParaNoMax THEN #sbParaNo := FALSE; #sbError := True; #siErrorId := 2; ELSIF #ParaNo < 1 THEN #sbParaNo := FALSE; #sbError := True; #siErrorId := 2; ELSE #sbParaNo := TRUE; #siParaNo := #ParaNo; IF #siErrorId = 2 THEN #siErrorId := 0; #sbError := False; END_IF; END_IF; #syAxisNo := #AxisNo; END_IF; // Starten IF #Start AND NOT #sbStart AND (#ParaNo <> 0) AND NOT #sbBusy THEN #sbReady := False; #sbError := False; #sbBusy := False; // Auftrag "Parameter lesen" erkennen IF NOT #ReadWrite THEN #sbRead := True; #sbWrStart := True; #sbRdStart := False; #sbWrite := False; #sbWrStart1 := False; #sbRdStart1 := False; #sbWrStart2 := False; #sbRdStart2 := False; // Referenzauftragsnummer erzeugen #siReqRef := #siReqRef + 1; // bei Uberschreitung wieder zurucksetzen und von vorne (Wertebereich von 0-255) IF #siReqRef > 255 THEN #siReqRef := 0; END_IF; // Auftrag "Parameter schreiben" erkennen ELSE #sbWrite := True; #sbWrStart1 := True; #sbRdStart1 := False; #sbWrStart2 := False; #sbRdStart2 := False; #sbRead := False; #sbWrStart := False; #sbRdStart := False; // Referenzauftragsnummer erzeugen #siReqRef := #siReqRef + 1; // bei Uberschreitung wieder zurucksetzen und von vorne (Wertebereich von 0-255) IF #siReqRef > 255 THEN #siReqRef := 0; END_IF; END_IF; // Fehler 4 und 5 wieder zurucknehmen IF (#siErrorId = 4) OR (#siErrorId = 5) THEN #sbError := False; #siErrorId := 0; END_IF; END_IF; // "Start commando" Flanke merken #sbStart := #Start; // Abbrechen IF NOT #Start THEN #siErrorCount := 0; // Schreib - oder Lesevorgang abbrechen #sbRead := False; #sbWrStart := False; #sbRdStart := False; #sbWrite := False; #sbWrStart1 := False; #sbRdStart1 := False; #sbWrStart2 := False; #sbRdStart2 := False; // Auftag ist noch beschaftigt => Fehler ausgeben IF #sbBusy THEN #sbError := True; #siErrorId := 4; #sbBusy := False; END_IF; END_IF; // Auftrag "Parameter lesen" wurde ausgelost IF #sbParaNo AND #sbRead AND NOT #sbWrite THEN // Auftrag "Parameter lesen" vorbereiten und abschicken IF #sbWrStart THEN // Abloschen des Sendepuffers IF NOT (#siParaNo = #siParaNoMax) THEN FOR #piCount := #siParaNo TO #siParaNoMax DO // Parameternummer des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siParaNo := 0; // Subindex des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siIndex := 0; END_FOR; END_IF; // Auftrags-HEADER erstellen // Auftragsreferenz #sxReqParaMulti.sxHeader.syReqRef := INT_TO_BYTE(#siReqRef); // Auftragskennung 0x01=Request Parameters #sxReqParaMulti.sxHeader.syReqId := B#16#01; // Achse #sxReqParaMulti.sxHeader.syAxisNo := #syAxisNo; // Anzahl Parameter #sxReqParaMulti.sxHeader.syParaNo := INT_TO_BYTE(#siParaNo); // Auftrags-PARAMETERADRESSE erstellen FOR #piCount := 1 TO #siParaNo DO // Parameternummer des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siParaNo := #sxParameter[#piCount].siParaNo; // Subindex des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siIndex := #sxParameter[#piCount].siIndex; END_FOR; // SCHREIBEN AZYKLISCH #piLenTele := #siLenHeader + #siLenParaMulti; #WRREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp LEN := INT_TO_UINT(#piLenTele), // maximale Lange DONE => #sbWrDone, // Schreibauftrag beendet BUSY => #sbWrBusy, // Slave beschaftigt ERROR => #sbWrError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code RECORD := #sxReqParaMulti); // Zeiger auf zu schreibenen Datensatzes // Ausgange setzen #sbBusy := #sbWrBusy; #sbDone := #sbWrDone; // Fehler auswerten IF #sbWrError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // Fehler ausgeben #sbError := #sbWrError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbWrError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // kein Fehler beim SCHEIBEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbWrBusy AND #sbWrDone THEN // Fehlerkennung zurucknehmen IF #siErrorId = 3 THEN #siErrorId := 0; #sbError := False; END_IF; #DiagId := W#16#00; // Schreibauftrag fertig melden und Leseantrag anstossen #sbWrStart := False; #sbRdStart := True; END_IF; END_IF; // Auftrag "Parameter lesen" vorbereiten und abschicken // vom Auftrag "Parameter lesen" die Antwort abwarten und dann auswerten IF #sbRdStart THEN // Abloschen des Empfangspuffers #sxRespParaMulti.sxHeader.syReqRef := B#16#00; #sxRespParaMulti.sxHeader.syReqId := B#16#00; #sxRespParaMulti.sxHeader.syAxisNo := B#16#00; #sxRespParaMulti.sxHeader.syParaNo := B#16#00; FOR #piCount := 1 TO #siLenParaMulti DO #sxRespParaMulti.sxData[#piCount] := B#16#00; END_FOR; // LESEN AZYKLISCH #piLenTele := #siLenHeader + #siLenParaMulti; #RDREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp MLEN := INT_TO_UINT(#piLenTele), // maximale Lange VALID => #pbValidSFB, // neuer Datensatz empfangen und gultig BUSY => #sbRdBusy, // Slave beschaftigt ERROR => #sbRdError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code LEN => #piLenSFB, // Lange des gelesenen Datensatzes RECORD := #sxRespParaMulti); // Zeiger auf gelesenen Datensatz // Ausgange setzen #sbBusy := #sbRdBusy; #sbDone := #pbValidSFB; // Fehler auswerten IF #sbRdError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // Fehler ausgeben #sbError := #sbRdError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbRdError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // Fehler : die Auftragsreferenz der Antwort ubertimmt nicht mit der Auftragsreferenz der Anfrage uberein ELSIF NOT (#siReqRef = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syReqRef)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // Fehler : falsche Auftragskennung zuruck erhalten ELSIF NOT (#sxRespParaMulti.sxHeader.syReqId = B#16#81 OR #sxRespParaMulti.sxHeader.syReqId = B#16#01) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // Fehler : die angeforderte Anzahl Parameter entspricht nicht der ubermittelten Anzahl Parameter uberein ELSIF NOT (#siParaNo = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syParaNo)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // Fehler : die Achse entspricht nicht der ubergebenen Achse ELSIF NOT (#syAxisNo = #sxRespParaMulti.sxHeader.syAxisNo) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart := False; #sbRdStart := False; #sbRead := False; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbRdBusy AND #pbValidSFB THEN // die angefragten Parameter auswerten und im Puffer abspeichern #piPointer := 1; #swParaError := 16#0; FOR #piCount := 1 TO #siParaNo DO // ermitteltes Format des Parameters abspeichern #sxParameter[#piCount].syFormat := #sxRespParaMulti.sxData[#piPointer]; // Format = Error ? = > gesendeter Parameter fehlerhaft IF (BYTE_TO_INT(#sxRespParaMulti.sxData[#piPointer]) = 68) THEN // Format = Error, zwei Bytes zu ubermittelten Fehlernummer zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #sbError := True; // ermittelte Fehlernummer im Puffer abspeichern #sxParameter[#piCount].swErrorNo := #pwWordHigh XOR #pwWordLow; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer eintragen IF #piCount = 1 THEN #swParaError := #swParaError OR W#16#01; ELSIF #piCount = 2 THEN #swParaError := #swParaError OR W#16#02; ELSIF #piCount = 3 THEN #swParaError := #swParaError OR W#16#04; ELSIF #piCount = 4 THEN #swParaError := #swParaError OR W#16#08; ELSIF #piCount = 5 THEN #swParaError := #swParaError OR W#16#10; ELSIF #piCount = 6 THEN #swParaError := #swParaError OR W#16#20; ELSIF #piCount = 7 THEN #swParaError := #swParaError OR W#16#40; ELSIF #piCount = 8 THEN #swParaError := #swParaError OR W#16#80; ELSIF #piCount = 9 THEN #swParaError := #swParaError OR W#16#100; ELSIF #piCount = 10 THEN #swParaError := #swParaError OR W#16#200; ELSIF #piCount = 11 THEN #swParaError := #swParaError OR W#16#400; ELSIF #piCount = 12 THEN #swParaError := #swParaError OR W#16#800; ELSIF #piCount = 13 THEN #swParaError := #swParaError OR W#16#1000; ELSIF #piCount = 14 THEN #swParaError := #swParaError OR W#16#2000; ELSIF #piCount = 15 THEN #swParaError := #swParaError OR W#16#4000; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError OR W#16#8000; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Format = Byte ? = > gesendeter Parameter ein Byte lang ohne Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#41) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#05) THEN // ermittelter Parameterwert eintragen (Byte) #sxParameter[#piCount].srValue := USINT_TO_REAL(BYTE_TO_USINT(#sxRespParaMulti.sxData[#piPointer + 2])); #sxParameter[#piCount].sdValue := 0; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Byte ? = > gesendeter Parameter ein Byte lang mit Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#02) THEN // ermittelter Parameterwert eintragen (Byte) #sxParameter[#piCount].srValue := SINT_TO_REAL(BYTE_TO_SINT(#sxRespParaMulti.sxData[#piPointer + 2])); #sxParameter[#piCount].sdValue := 0; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Word ? = > gesendeter Parameter zwei Bytes lang ohne Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#42) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#06) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#0A) THEN // Format = Word, zwei Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; // ermittelter Parameterwert eintragen (Word) #sxParameter[#piCount].srValue := UINT_TO_REAL(WORD_TO_UINT(#pwWord1)); #sxParameter[#piCount].sdValue := 0; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Word ? = > gesendeter Parameter zwei Bytes lang mit Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#03) THEN // Format = Word, zwei Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; // ermittelter Parameterwert eintragen (Word) #sxParameter[#piCount].srValue := INT_TO_REAL(WORD_TO_INT(#pwWord1)); #sxParameter[#piCount].sdValue := 0; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Double Word ? = > gesendeter Parameter vier Bytes lang ohne Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#43) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#07) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#0D) THEN // Format = Double Word, vier Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 4]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 5]); #pwWord2 := #pwWordHigh XOR #pwWordLow; #pdDWordHigh := SHL(IN := WORD_TO_DWORD(#pwWord1), N := 16); #pdDWordLow := WORD_TO_DWORD(#pwWord2); // ermittelter Parameterwert eintragen (Word) #sxParameter[#piCount].srValue := 0.0; #sxParameter[#piCount].sdValue := DWORD_TO_DINT(#pdDWordHigh XOR #pdDWordLow); // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Format = Double Word ? = > gesendeter Parameter vier Bytes lang mit Vorzeichen ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#04) THEN // Format = Double Word, vier Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 4]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 5]); #pwWord2 := #pwWordHigh XOR #pwWordLow; #pdDWordHigh := SHL(IN := WORD_TO_DWORD(#pwWord1), N := 16); #pdDWordLow := WORD_TO_DWORD(#pwWord2); // ermittelter Parameterwert eintragen (Word) #sxParameter[#piCount].srValue := 0.0; #sxParameter[#piCount].sdValue := DWORD_TO_DINT(#pdDWordHigh XOR #pdDWordLow); // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Format = Double Word ? = > gesendeter Parameter vier Bytes lang (FloatingPoint) ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#08) THEN // Format = Double Word, vier Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 4]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 5]); #pwWord2 := #pwWordHigh XOR #pwWordLow; #pdDWordHigh := SHL(IN := WORD_TO_DWORD(#pwWord1), N := 16); #pdDWordLow := WORD_TO_DWORD(#pwWord2); // ermittelter Parameterwert eintragen (Word) #sxParameter[#piCount].srValue := DWORD_TO_REAL(#pdDWordHigh XOR #pdDWordLow); #sxParameter[#piCount].sdValue := 0; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Unbekanter Datentyp ELSE #siErrorId := 5; #sbError := True; #sbDone := False; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer eintragen IF #piCount = 1 THEN #swParaError := #swParaError OR W#16#01; ELSIF #piCount = 2 THEN #swParaError := #swParaError OR W#16#02; ELSIF #piCount = 3 THEN #swParaError := #swParaError OR W#16#04; ELSIF #piCount = 4 THEN #swParaError := #swParaError OR W#16#08; ELSIF #piCount = 5 THEN #swParaError := #swParaError OR W#16#10; ELSIF #piCount = 6 THEN #swParaError := #swParaError OR W#16#20; ELSIF #piCount = 7 THEN #swParaError := #swParaError OR W#16#40; ELSIF #piCount = 8 THEN #swParaError := #swParaError OR W#16#80; ELSIF #piCount = 9 THEN #swParaError := #swParaError OR W#16#100; ELSIF #piCount = 10 THEN #swParaError := #swParaError OR W#16#200; ELSIF #piCount = 11 THEN #swParaError := #swParaError OR W#16#400; ELSIF #piCount = 12 THEN #swParaError := #swParaError OR W#16#800; ELSIF #piCount = 13 THEN #swParaError := #swParaError OR W#16#1000; ELSIF #piCount = 14 THEN #swParaError := #swParaError OR W#16#2000; ELSIF #piCount = 15 THEN #swParaError := #swParaError OR W#16#4000; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError OR W#16#8000; END_IF; EXIT; //Bei erstem unbekannten Datentyp abrechen END_IF; END_FOR; // die angefragten Parameter auswerten und im Puffer abspeichern // Fehlerkennung zurucknehmen IF (#siErrorId = 3) OR (#siErrorId = 1) THEN #siErrorId := 0; #sbError := False; END_IF; #DiagId := W#16#00; // Auftrag : Parameter lesen ist abgeschlossen #sbRdStart := False; #sbRead := False; END_IF; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig END_IF; // vom Auftrag "Parameter lesen" die Antwort abwarten und dann auswerten END_IF; // Auftrag "Parameter lesen" wurde ausgelost // Auftrag "Parameter schreiben" wurde ausgelost IF #sbParaNo AND NOT #sbRead AND #sbWrite THEN // Auftrag "Parameter schreiben" bzw. "andern" besteht aus zwei Auftragen // 1. Teilauftrag "Parameter lesen" // 2. Teilauftrag "Parameter schreiben bzw. andern" // 1. Teilauftrag "Parameter lesen" vorbereiten und abschicken IF #sbWrStart1 THEN // Abloschen des Sendepuffers IF NOT (#siParaNo = #siParaNoMax) THEN FOR #piCount := #siParaNo TO #siParaNoMax DO // Parameternummer des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siParaNo := 0; // Subindex des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siIndex := 0; END_FOR; END_IF; // Auftrags-HEADER erstellen // Auftragsreferenz #sxReqParaMulti.sxHeader.syReqRef := INT_TO_BYTE(#siReqRef); // Auftragskennung 0x01=Request Parameters #sxReqParaMulti.sxHeader.syReqId := B#16#01; // Achse #sxReqParaMulti.sxHeader.syAxisNo := #syAxisNo; // Anzahl Parameter #sxReqParaMulti.sxHeader.syParaNo := INT_TO_BYTE(#siParaNo); // Auftrags-PARAMETERADRESSE erstellen FOR #piCount := 1 TO #siParaNo DO // Parameternummer des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siParaNo := #sxParameter[#piCount].siParaNo; // Subindex des Parameters #sxReqParaMulti.sxParaAdress[#piCount].siIndex := #sxParameter[#piCount].siIndex; END_FOR; // SCHREIBEN AZYKLISCH #piLenTele := #siLenHeader + #siLenParaMulti; #WRREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp LEN := INT_TO_UINT(#piLenTele), // maximale Lange DONE => #sbWrDone, // Schreibauftrag beendet BUSY => #sbWrBusy, // Slave beschaftigt ERROR => #sbWrError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code RECORD := #sxReqParaMulti); // Zeiger auf zu schreibenen Datensatz // Ausgange setzen #sbBusy := #sbWrBusy; #sbDone := #sbWrDone; // Fehler auswerten IF #sbWrError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // Fehler ausgeben #sbError := #sbWrError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbWrError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // kein Fehler beim SCHEIBEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbWrBusy AND #sbWrDone THEN // Fehlerkennung zurucknehmen IF (#siErrorId = 3) THEN #siErrorId := 0; #sbError := False; END_IF; #DiagId := W#16#00; // Schreibauftrag fertig melden und Leseantrag anstossen #sbWrStart1 := False; #sbRdStart1 := True; END_IF; END_IF; // 1. Teilauftrag "Parameter lesen" vorbereiten und abschicken // vom 1. Teilauftrag "Parameter lesen" die Antwort abwarten und dann auswerten IF #sbRdStart1 THEN // Abloschen des Empfangspuffers #sxRespParaMulti.sxHeader.syReqRef := B#16#00; #sxRespParaMulti.sxHeader.syReqId := B#16#00; #sxRespParaMulti.sxHeader.syAxisNo := B#16#00; #sxRespParaMulti.sxHeader.syParaNo := B#16#00; FOR #piCount := 1 TO #siLenParaMulti DO #sxRespParaMulti.sxData[#piCount] := B#16#00; END_FOR; // LESEN AZYKLISCH #piLenTele := #siLenHeader + #siLenParaMulti; #RDREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp MLEN := INT_TO_UINT(#piLenTele), // maximale Lange VALID => #pbValidSFB, // neuer Datensatz empfangen und gultig BUSY => #sbRdBusy, // Slave beschaftigt ERROR => #sbRdError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code LEN => #piLenSFB, // Lange des gelesenen Datensatzes RECORD := #sxRespParaMulti); // Zeiger auf gelesenen Datensatz // Ausgange setzen #sbBusy := #sbRdBusy; #sbDone := #pbValidSFB; // Fehler auswerten IF #sbRdError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // Fehler ausgeben #sbError := #sbRdError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbRdError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // Fehler : die Auftragsreferenz der Antwort ubertimmt nicht mit der Auftragsreferenz der Anfrage uberein ELSIF NOT (#siReqRef = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syReqRef)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // Fehler : falsche Auftragskennung zuruck erhalten ELSIF NOT (#sxRespParaMulti.sxHeader.syReqId = B#16#81 OR #sxRespParaMulti.sxHeader.syReqId = B#16#01) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // Fehler : die angeforderte Anzahl Parameter entspricht nicht der ubermittelten Anzahl Parameter uberein ELSIF NOT (#siParaNo = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syParaNo)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // Fehler : die Achse entspricht nicht der ubergebenen Achse ELSIF NOT (#syAxisNo = #sxRespParaMulti.sxHeader.syAxisNo) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart1 := False; #sbRdStart1 := False; #sbWrite := False; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbRdBusy AND #pbValidSFB THEN // die angefragten Parameter auswerten und im Puffer abspeichern #piPointer := 1; #swParaError := 16#0; FOR #piCount := 1 TO #siParaNo DO // ermitteltes Format des Parameters abspeichern #sxParameter[#piCount].syFormat := #sxRespParaMulti.sxData[#piPointer]; // Format = Error ? = > gesendeter Parameter fehlerhaft IF (BYTE_TO_INT(#sxRespParaMulti.sxData[#piPointer]) = 68) THEN // Format = Error, zwei Bytes zu ubermittelten Fehlernummer zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #sbError := True; // ermittelte Fehlernummer im Puffer abspeichern #sxParameter[#piCount].swErrorNo := #pwWordHigh XOR #pwWordLow; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer eintragen IF #piCount = 1 THEN #swParaError := #swParaError OR W#16#01; ELSIF #piCount = 2 THEN #swParaError := #swParaError OR W#16#02; ELSIF #piCount = 3 THEN #swParaError := #swParaError OR W#16#04; ELSIF #piCount = 4 THEN #swParaError := #swParaError OR W#16#08; ELSIF #piCount = 5 THEN #swParaError := #swParaError OR W#16#10; ELSIF #piCount = 6 THEN #swParaError := #swParaError OR W#16#20; ELSIF #piCount = 7 THEN #swParaError := #swParaError OR W#16#40; ELSIF #piCount = 8 THEN #swParaError := #swParaError OR W#16#80; ELSIF #piCount = 9 THEN #swParaError := #swParaError OR W#16#100; ELSIF #piCount = 10 THEN #swParaError := #swParaError OR W#16#200; ELSIF #piCount = 11 THEN #swParaError := #swParaError OR W#16#400; ELSIF #piCount = 12 THEN #swParaError := #swParaError OR W#16#800; ELSIF #piCount = 13 THEN #swParaError := #swParaError OR W#16#1000; ELSIF #piCount = 14 THEN #swParaError := #swParaError OR W#16#2000; ELSIF #piCount = 15 THEN #swParaError := #swParaError OR W#16#4000; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError OR W#16#8000; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Format = Byte ? = > gesendeter Parameter ein Byte lang ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#41) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#02) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#05) THEN // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Word ? = > gesendeter Parameter zwei Bytes lang ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#42) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#03) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#06) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#0A) THEN // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 4; // Format = Double Word ? = > gesendeter Parameter vier Bytes lang ELSIF (#sxRespParaMulti.sxData[#piPointer] = B#16#43) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#04) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#07) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#08) OR (#sxRespParaMulti.sxData[#piPointer] = B#16#0D) THEN // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; // Unbekanter Datentyp ELSE #siErrorId := 5; #sbError := True; #sbDone := False; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer eintragen IF #piCount = 1 THEN #swParaError := #swParaError OR W#16#01; ELSIF #piCount = 2 THEN #swParaError := #swParaError OR W#16#02; ELSIF #piCount = 3 THEN #swParaError := #swParaError OR W#16#04; ELSIF #piCount = 4 THEN #swParaError := #swParaError OR W#16#08; ELSIF #piCount = 5 THEN #swParaError := #swParaError OR W#16#10; ELSIF #piCount = 6 THEN #swParaError := #swParaError OR W#16#20; ELSIF #piCount = 7 THEN #swParaError := #swParaError OR W#16#40; ELSIF #piCount = 8 THEN #swParaError := #swParaError OR W#16#80; ELSIF #piCount = 9 THEN #swParaError := #swParaError OR W#16#100; ELSIF #piCount = 10 THEN #swParaError := #swParaError OR W#16#200; ELSIF #piCount = 11 THEN #swParaError := #swParaError OR W#16#400; ELSIF #piCount = 12 THEN #swParaError := #swParaError OR W#16#800; ELSIF #piCount = 13 THEN #swParaError := #swParaError OR W#16#1000; ELSIF #piCount = 14 THEN #swParaError := #swParaError OR W#16#2000; ELSIF #piCount = 15 THEN #swParaError := #swParaError OR W#16#4000; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError OR W#16#8000; END_IF; EXIT; //Bei erstem unbekannten Datentyp abrechen END_IF; END_FOR; // die angefragten Parameter auswerten und im Puffer abspeichern // Fehlerkennung zurucknehmen IF (#siErrorId = 3) OR (#siErrorId = 1) THEN #siErrorId := 0; #sbError := False; END_IF; #DiagId := W#16#00; // 1. Teilauftrag "Parameter lesen" ist abgeschlossen #sbRdStart1 := False; // einer der gesendeten Parameter ist fehlerhaft => Abbruch, kein "Parameter schreiben" erforderlich IF (#swParaError = W#16#00) THEN #sbWrStart2 := True; ELSE #sbWrStart2 := False; END_IF; END_IF; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig END_IF; // vom 1. Teilauftrag "Parameter lesen" die Antwort abwarten und dann auswerten // 2. Teilauftrag "Parameter schreiben bzw. andern" vorbereiten und abschicken IF #sbWrStart2 THEN // Abloschen des Sendepuffers FOR #piCount := 1 TO #siLenChaPara DO // Parameteradresse und Parameterwert des Parameters #sxChaParaMulti.sxData[#piCount] := B#16#00; END_FOR; // Auftrags-HEADER erstellen // Auftragsreferenz #sxChaParaMulti.sxHeader.syReqRef := INT_TO_BYTE(#siReqRef); // Auftragskennung 0x01=Request Parameters | 0x02=Change Parameters #sxChaParaMulti.sxHeader.syReqId := B#16#02; // Achse #sxChaParaMulti.sxHeader.syAxisNo := #syAxisNo; // Anzahl Parameter #sxChaParaMulti.sxHeader.syParaNo := INT_TO_BYTE(#siParaNo); // Auftrags-PARAMETERADRESSE erstellen #piPointer := 1; FOR #piCount := 1 TO #siParaNo DO // Attribute of parameters (0x10=Value, 0x30=Text) #sxChaParaMulti.sxData[#piPointer] := B#16#10; // No. of elements (DEC: for single elements=1) #sxChaParaMulti.sxData[#piPointer + 1] := B#16#01; // Parameternummer des Parameters #sxChaParaMulti.sxData[#piPointer + 3] := INT_TO_BYTE(#sxParameter[#piCount].siParaNo); #sxChaParaMulti.sxData[#piPointer + 2] := WORD_TO_BYTE(SHR(IN := INT_TO_WORD(#sxParameter[#piCount].siParaNo), N := 8)); // Subindex des Parameters #sxChaParaMulti.sxData[#piPointer + 5] := INT_TO_BYTE(#sxParameter[#piCount].siIndex); #sxChaParaMulti.sxData[#piPointer + 4] := WORD_TO_BYTE(SHR(IN := INT_TO_WORD(#sxParameter[#piCount].siIndex), N := 8)); // Zeiger auf nachsten Parameteradresse setzen #piPointer := #piPointer + 6; END_FOR; // Auftrags-PARAMETERADRESSE erstellen // Auftrags-PARAMETERVALUE erstellen FOR #piCount := 1 TO #siParaNo DO // Format (BYTE, WORD, DWORD des Parameterwert ubergeben #sxChaParaMulti.sxData[#piPointer] := #sxParameter[#piCount].syFormat; // Number of value #sxChaParaMulti.sxData[#piPointer + 1] := B#16#01; // Value of parameter in Bytes IF (#sxParameter[#piCount].syFormat = B#16#41) OR (#sxParameter[#piCount].syFormat = B#16#02) OR (#sxParameter[#piCount].syFormat = B#16#05) THEN #sxChaParaMulti.sxData[#piPointer + 2] := WORD_TO_BYTE(DWORD_TO_WORD(DINT_TO_DWORD(REAL_TO_DINT(#sxParameter[#piCount].srValue)))); #sxChaParaMulti.sxData[#piPointer + 3] := 16#00; //WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := DINT_TO_DWORD(REAL_TO_DINT(#sxParameter[#piCount].srValue)), N := 8))); // Zeiger auf nachsten Parameteradresse setzen #piPointer := #piPointer + 4; // Value of parameter in Word ELSIF (#sxParameter[#piCount].syFormat = B#16#42) OR (#sxParameter[#piCount].syFormat = B#16#03) OR (#sxParameter[#piCount].syFormat = B#16#06) THEN #sxChaParaMulti.sxData[#piPointer + 3] := WORD_TO_BYTE(DWORD_TO_WORD(DINT_TO_DWORD(REAL_TO_DINT(#sxParameter[#piCount].srValue)))); #sxChaParaMulti.sxData[#piPointer + 2] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := DINT_TO_DWORD(REAL_TO_DINT(#sxParameter[#piCount].srValue)), N := 8))); // Zeiger auf nachsten Parameteradresse setzen #piPointer := #piPointer + 4; // Value of parameter in DWord (Double Word ohne Vorzeichen/Double Word mit Vorzeichen) ELSIF (#sxParameter[#piCount].syFormat = B#16#43) OR (#sxParameter[#piCount].syFormat = B#16#04) OR (#sxParameter[#piCount].syFormat = B#16#07) THEN #sxChaParaMulti.sxData[#piPointer + 5] := WORD_TO_BYTE(DWORD_TO_WORD(DINT_TO_DWORD(#sxParameter[#piCount].sdValue))); #sxChaParaMulti.sxData[#piPointer + 4] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := DINT_TO_DWORD(#sxParameter[#piCount].sdValue), N := 8))); #sxChaParaMulti.sxData[#piPointer + 3] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := DINT_TO_DWORD(#sxParameter[#piCount].sdValue), N := 16))); #sxChaParaMulti.sxData[#piPointer + 2] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := DINT_TO_DWORD(#sxParameter[#piCount].sdValue), N := 24))); // Zeiger auf nachsten Parameteradresse setzen #piPointer := #piPointer + 6; // Value of parameter in DWord (FloatingPoint) ELSIF (#sxParameter[#piCount].syFormat = B#16#08) THEN #sxChaParaMulti.sxData[#piPointer + 5] := WORD_TO_BYTE(DWORD_TO_WORD(REAL_TO_DWORD(#sxParameter[#piCount].srValue))); #sxChaParaMulti.sxData[#piPointer + 4] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := REAL_TO_DWORD(#sxParameter[#piCount].srValue), N := 8))); #sxChaParaMulti.sxData[#piPointer + 3] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := REAL_TO_DWORD(#sxParameter[#piCount].srValue), N := 16))); #sxChaParaMulti.sxData[#piPointer + 2] := WORD_TO_BYTE(DWORD_TO_WORD(SHR(IN := REAL_TO_DWORD(#sxParameter[#piCount].srValue), N := 24))); // Zeiger auf nachsten Parameteradresse setzen #piPointer := #piPointer + 6; END_IF; END_FOR; // Auftrags-PARAMETERVALUE erstellen // SCHREIBEN AZYKLISCH #piLenTele := #siLenHeader + #siLenChaPara; #WRREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp LEN := INT_TO_UINT(#piLenTele), // maximale Lange DONE => #sbWrDone, // Schreibauftrag beendet BUSY => #sbWrBusy, // Slave beschaftigt ERROR => #sbWrError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code RECORD := #sxChaParaMulti); // Zeiger auf zu schreibenen Datensatzes // Ausgange setzen #sbBusy := #sbWrBusy; #sbDone := #sbWrDone; // Fehler auswerten IF #sbWrError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #sbError := False; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // Fehler ausgeben #sbError := #sbWrError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbWrError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // kein Fehler beim SCHEIBEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbWrBusy AND #sbWrDone THEN // Fehlerkennung zurucknehmen #DiagId := W#16#00; // Schreibauftrag fertig melden und Leseantrag anstossen #sbWrStart2 := False; #sbRdStart2 := True; END_IF; END_IF; // 2. Teilauftrag "Parameter schreiben bzw. andern" vorbereiten und abschicken // vom 2. Teilauftrag "Parameter schreiben bzw. andern" die Antwort abwarten und dann auswerten IF #sbRdStart2 THEN // Abloschen des Empfangspuffers #sxRespParaMulti.sxHeader.syReqRef := B#16#00; #sxRespParaMulti.sxHeader.syReqId := B#16#00; #sxRespParaMulti.sxHeader.syAxisNo := B#16#00; #sxRespParaMulti.sxHeader.syParaNo := B#16#00; FOR #piCount := 1 TO #siLenParaMulti DO #sxRespParaMulti.sxData[#piCount] := B#16#00; END_FOR; // LESEN AZYKLISCH #piLenTele := #siLenHeader + #siLenParaMulti; #RDREC_1(REQ := True, // Startimpuls ID := #hardwareId, // Diagnoseadresse INDEX := 47, // Rahmentyp MLEN := INT_TO_UINT(#piLenTele), // maximale Lange VALID => #pbValidSFB, // neuer Datensatz empfangen und gultig BUSY => #sbRdBusy, // Slave beschaftigt ERROR => #sbRdError, // Fehler beim Schreiben STATUS => #pdStatus, // Status[1] = Error => Status[2] Error Decode + Status[3] Error Code LEN => #piLenSFB, // Lange des gelesenen Datensatzes RECORD := #sxRespParaMulti); // Zeiger auf gelesenen Datensatz // Ausgange setzen #sbBusy := #sbRdBusy; #sbDone := #pbValidSFB; // Fehler auswerten IF #sbRdError THEN // Fehlerstatus aus dem Doppelwort filtern und weitergeben #pwWord1 := DWORD_TO_WORD(SHR(IN := (#pdStatus AND DW#16#FFFF00), N := 8)); // Fehlerstatus setzen #siErrorId := 3; #DiagId := #pwWord1; //Temporarer Fehler: #pdStatus = 80A7, 80B5, 80C0, 80C1, 80C2, 80C3 oder 80C4 zulassen und nocheinmal versuchen IF NOT (#pwWord1 = DW#16#80A7) AND NOT (#pwWord1 = DW#16#80B5) AND NOT (#pwWord1 = DW#16#80C0) AND NOT (#pwWord1 = DW#16#80C1) AND NOT (#pwWord1 = DW#16#80C2) AND NOT (#pwWord1 = DW#16#80C3) AND NOT (#pwWord1 = DW#16#80C4) THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // Fehler ausgeben #sbError := #sbRdError; ELSE // Fehlerwiederholauftrag ?? IF #siErrorCount = #siMaxErrCount THEN // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; //Fehlerzahler zurucksetzen #siErrorCount := 0; // Fehler ausgeben #sbError := #sbRdError; // nix tun bis Zahler uberlauft ELSE #siErrorCount := #siErrorCount + 1; END_IF; END_IF; // Fehler : die Auftragsreferenz der Antwort ubertimmt nicht mit der Auftragsreferenz der Anfrage uberein ELSIF NOT (#siReqRef = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syReqRef)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // Fehler : falsche Auftragskennung zuruck erhalten ELSIF NOT (#sxRespParaMulti.sxHeader.syReqId = B#16#82 OR #sxRespParaMulti.sxHeader.syReqId = B#16#02) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // Fehler : die angeforderte Anzahl Parameter entspricht nicht der ubermittelten Anzahl Parameter uberein ELSIF NOT (#siParaNo = BYTE_TO_INT(#sxRespParaMulti.sxHeader.syParaNo)) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // Fehler : die Achse entspricht nicht der ubergebenen Achse ELSIF NOT (#syAxisNo = #sxRespParaMulti.sxHeader.syAxisNo) AND NOT #sbRdBusy AND #pbValidSFB THEN #siErrorId := 1; #sbError := True; #sbDone := False; // Wiederholungsauftrag wieder zurucknehmen #sbWrStart2 := False; #sbRdStart2 := False; #sbWrite := False; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig ELSIF NOT #sbRdBusy AND #pbValidSFB THEN // 2. Teilauftrag "Parameter schreiben bzw. andern" negative Ruckmeldung erhalten IF #sxRespParaMulti.sxHeader.syReqId = B#16#82 THEN // die angefragten Parameter auswerten und im Puffer abspeichern #piPointer := 1; #swParaError := 16#0; FOR #piCount := 1 TO #siParaNo DO // Format des Parameters auswerten, bei Format = Error Fehler auswerten IF (BYTE_TO_INT(#sxRespParaMulti.sxData[#piPointer]) = 68) THEN // Fehlerwert ermitteln und abspeichern // Format = Word, zwei Bytes zu ubermitteltem Parameterwert zusammenfassen #pwWordHigh := SHL(IN := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 2]), N := 8); #pwWordLow := BYTE_TO_WORD(#sxRespParaMulti.sxData[#piPointer + 3]); #pwWord1 := #pwWordHigh XOR #pwWordLow; #sbError := True; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; #sxParameter[#piCount].swErrorNo := #pwWord1; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer eintragen IF #piCount = 1 THEN #swParaError := #swParaError OR W#16#01; ELSIF #piCount = 2 THEN #swParaError := #swParaError OR W#16#02; ELSIF #piCount = 3 THEN #swParaError := #swParaError OR W#16#04; ELSIF #piCount = 4 THEN #swParaError := #swParaError OR W#16#08; ELSIF #piCount = 5 THEN #swParaError := #swParaError OR W#16#10; ELSIF #piCount = 6 THEN #swParaError := #swParaError OR W#16#20; ELSIF #piCount = 7 THEN #swParaError := #swParaError OR W#16#40; ELSIF #piCount = 8 THEN #swParaError := #swParaError OR W#16#80; ELSIF #piCount = 9 THEN #swParaError := #swParaError OR W#16#100; ELSIF #piCount = 10 THEN #swParaError := #swParaError OR W#16#200; ELSIF #piCount = 11 THEN #swParaError := #swParaError OR W#16#400; ELSIF #piCount = 12 THEN #swParaError := #swParaError OR W#16#800; ELSIF #piCount = 13 THEN #swParaError := #swParaError OR W#16#1000; ELSIF #piCount = 14 THEN #swParaError := #swParaError OR W#16#2000; ELSIF #piCount = 15 THEN #swParaError := #swParaError OR W#16#4000; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError OR W#16#8000; END_IF; // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 6; ELSE // Zeiger auf nachsten Parametersatz setzen #piPointer := #piPointer + 2; // Die Fehlerhaftigkeit des erkannten Parameter in der Fehlernummer loschen IF #piCount = 1 THEN #swParaError := #swParaError AND W#16#FFFE; ELSIF #piCount = 2 THEN #swParaError := #swParaError AND W#16#FFFD; ELSIF #piCount = 3 THEN #swParaError := #swParaError AND W#16#FFFB; ELSIF #piCount = 4 THEN #swParaError := #swParaError AND W#16#FFF7; ELSIF #piCount = 5 THEN #swParaError := #swParaError AND W#16#FFEF; ELSIF #piCount = 6 THEN #swParaError := #swParaError AND W#16#FFDF; ELSIF #piCount = 7 THEN #swParaError := #swParaError AND W#16#FFBF; ELSIF #piCount = 8 THEN #swParaError := #swParaError AND W#16#FF7F; ELSIF #piCount = 9 THEN #swParaError := #swParaError AND W#16#FEFF; ELSIF #piCount = 10 THEN #swParaError := #swParaError AND W#16#FDFF; ELSIF #piCount = 11 THEN #swParaError := #swParaError AND W#16#FBFF; ELSIF #piCount = 12 THEN #swParaError := #swParaError AND W#16#F7FF; ELSIF #piCount = 13 THEN #swParaError := #swParaError AND W#16#EFFF; ELSIF #piCount = 14 THEN #swParaError := #swParaError AND W#16#DFFF; ELSIF #piCount = 15 THEN #swParaError := #swParaError AND W#16#BFFF; ELSIF #piCount = #siParaNo THEN #swParaError := #swParaError AND W#16#7FFF; END_IF; // ermittelte Fehlernummer im Puffer zurucksetzen #sxParameter[#piCount].swErrorNo := W#16#00; END_IF; END_FOR; // die angefragten Parameter auswerten und im Puffer abspeichern END_IF; // 2. Teilauftrag "Parameter schreiben bzw. andern" negative Ruckmeldung erhalten // Fehlerkennung zurucknehmen IF (#siErrorId = 3) OR (#siErrorId = 1) THEN #siErrorId := 0; #sbError := False; END_IF; #DiagId := W#16#00; // 2. Teilauftrag "Parameter schreiben bzw. andern" ist abgeschlossen #sbRdStart2 := False; #sbWrite := False; END_IF; // kein Fehler beim LESEN AZYKLISCH und Auftrag fertig END_IF; // vom 2. Teilauftrag "Parameter schreiben bzw. andern" die Antwort abwarten und dann auswerten END_IF; // Auftrag "Parameter schreiben" wurde ausgelost #pdDWordHigh := SHL(IN := INT_TO_DWORD(#siErrorId), N := 16); #pdDWordLow := WORD_TO_DWORD(#swParaError); // ermittelter Parameterwert eintragen (Word) #ErrorId := #pdDWordHigh XOR #pdDWordLow; // Initialisierung von Ausgangen #Busy := #sbBusy; #Error := #sbError; // Anderung wegen verhalten von Ready #Done := #sbDone; // Prufen, ob Auftrag abgeschlossen ist IF ((#Error OR #Done) AND NOT #sbReady) THEN #Ready := True; #sbReady := True; ELSE #Ready := False; END_IF;