FUNCTION_BLOCK FB 100
TITLE =Diagnose DP-Slaves an CP342-5
AUTHOR : PN_DP
VERSION : 0.1
VAR
DP_RECV_STATUS : WORD ; //Komm-Statuswort DP_RECV
DP_RECV_DPSTATUS : BYTE ; //DP-Status von DP_RECV
DP_RECV_ERROR : BOOL ; //Kommunikation-Error DP_RECV
DP_RECV_NDR : BOOL ;
DP_DIAG0_Active : BOOL ; //DP-Stationsliste lesen aktiv
DP_DIAG2_Active : BOOL ; //DP-Einzeldiagnose aktiv
DP_DIAG_ADR : BYTE ; //Adresse der aktuellen Einzeldiagnose
END_VAR
VAR_TEMP
DP_DIAG_STATUS : WORD ;
DP_DIAG_DIAGLNG : BYTE ;
DP_DIAG_NDR : BOOL ;
DP_DIAG_ERROR : BOOL ;
DP_DIAG_LISTE : ARRAY [1 .. 4 ] OF DWORD ;
END_VAR
BEGIN
NETWORK
TITLE =DP-Slaves Eingänge einlesen
CALL "DP_RECV" ( //FC2
CPLADDR := W#16#160,
RECV := P#DB20.DBX0.0 BYTE 190,
NDR := #DP_RECV_NDR,
ERROR := #DP_RECV_ERROR,
STATUS := #DP_RECV_STATUS,
DPSTATUS := #DP_RECV_DPSTATUS);
NETWORK
TITLE =Diagnose: DP-Slaves 07...18 ausgefallen?
//DP_RECV_DPSTATUS.0 muß 0 sein = Masterbetrieb
//DP_RECV_DPSTATUS.1 = 0 : alle Slave vorhanden
U #DP_DIAG2_Active; //Einzeldiagnose(2) lesen aktiv
SPB ESL;
O( ;
L W#16#3; //DP_RECV_DPSTATUS.1+.0 auswerten
L #DP_RECV_DPSTATUS;
XOW W#16#1; //DP_RECV_DPSTATUS.0 0->1 umdrehen
UW ; //wenn beide Bits=1 -> ergibt 3
==I ; //Stationsliste(0) lesen sinvoll
) ;
O #DP_DIAG0_Active;
= #DP_DIAG0_Active;
L 0;
SPBN ASOK; //alle Slaves vorhanden (AKKU1=0)
CALL "DP_DIAG" ( //FC3
CPLADDR := W#16#160,
DTYPE := B#16#0, //0=Stationsliste lesen
STATION := B#16#0,
DIAG := "DB_DP".LIST_SLAVES_NOT_PRESENT,
NDR := #DP_DIAG_NDR,
ERROR := #DP_DIAG_ERROR,
STATUS := #DP_DIAG_STATUS,
DIAGLNG := #DP_DIAG_DIAGLNG);
U( ;
L W#16#8182; //CP342-5 in STOP
L #DP_DIAG_STATUS;
==I ;
) ;
UN #DP_DIAG_NDR;
UN #DP_DIAG_ERROR;
O #DP_DIAG_NDR;
O #DP_DIAG_ERROR;
R #DP_DIAG0_Active;
U( ;
L 0;
L #DP_DIAG_STATUS;
==I ;
) ;
U #DP_DIAG_NDR; //neue Stationsliste(0) gelesen
UN #DP_DIAG_ERROR;
SPBN ESL;
//aktuelle Stationsliste gelesen
L "DB_DP".LIST_SLAVES_NOT_PRESENT[1];
SLD 3; //DP 3...18 -> WORD
TAD ;
TAW ;
ASOK: T "TRx_notPresent"; //bei SPB ASOK: AKKU1=0
ESL: L "TRx_notPresent";
NETWORK
TITLE =Diagnose: DP-Slave Einzeldiagnose auf "notReady"
//Ereignisgesteuerte Einzeldiagnose ist nicht sicher
//mindestens 1x müssen sowieso alle Slaves abgefragt werden
//besser zyklisch reihum jeden Slave abfragen
//12 Slaves *80ms (?) = ca. alle 1s rum
U #DP_DIAG0_Active; //Stationsliste(0) lesen aktiv
SPB EED;
S #DP_DIAG2_Active;
CALL "DP_DIAG" (
CPLADDR := W#16#160,
DTYPE := B#16#2, //2=Einzeldiagnose lesen
STATION := #DP_DIAG_ADR,
DIAG := "DB_DP".SLAVE_STATIONSTATUS,
NDR := #DP_DIAG_NDR,
ERROR := #DP_DIAG_ERROR,
STATUS := #DP_DIAG_STATUS,
DIAGLNG := #DP_DIAG_DIAGLNG);
U #DP_DIAG_NDR; //neue Einzeldiagnose(2) gelesen
UN #DP_DIAG_ERROR;
SPBN EEDA;
//aktuelle Einzeldiagnose(2) gelesen
L "DB_DP".SLAVE_STATIONSTATUS[1]; //"DB_DP".DBB16
//.0: StationNonExistent / .1: StationNotReady
// "DB_DP".DBX 16.0 //Stationbyte1.0:NonExistent
// "DB_DP".DBX 16.1 //Stationbyte1.1:NotReady
//Bitadresse in MW "TRx_notReady" berechnen
L #DP_DIAG_ADR; //Anzahl SRD (z.B. 7)
L DW#16#40000; // 100 00000000 00000000
SRD ; // 000 00001000 00000000
// DP-Adr: 34567890 12345678
//Stationbyte1.1:StationNotReady auswerten
U DB101.DBX 16.1; //Stationbyte1.1:NotReady
SPBN LNR; //0: Ready -> NotReady[x] löschen
// 1->setzen
L "TRx_notReady"; //1: NotReady -> NotReady[x] setzen
OW ; // setzen
SPA TNR;
// 0->löschen
LNR: INVD ; // 111 11110111 11111111
L "TRx_notReady";
UW ; // löschen
TNR: T "TRx_notReady";
//Einzeldiagnose(2) beendet?
EEDA: O #DP_DIAG_NDR;
O #DP_DIAG_ERROR;
SPBN EED;
R #DP_DIAG2_Active;
//zum nächsten DP-Slave weiterschalten
L 18; //höchste Slave-Adresse
L #DP_DIAG_ADR;
INC 1;
<I ;
SPBN TADR;
L 7; //niedrigste Slave-Adresse
TADR: T #DP_DIAG_ADR;
//OK, Einzeldiagnose(2) abgeschlossen
EED: L "TRx_notReady"; //Liste: gestört
L "TRx_notPresent"; //Liste: ganz ausgefallen
OW ;
T "DB_Visu".TRx_notReady; //-> Visu-Liste: notReady
END_FUNCTION_BLOCK