Aufbau des CAN-Interfaces
Je nach ausgewählter Option sieht das CAN-Interface unterschiedlich aus. Ein 11 Bit Identifier Interface ist anders aufgebaut als ein 29 Bit Identifier Interface. Zusätzlich kann das Interface die Transaction Number wie auch den Time Stamp beinhalten. Bei Verwendung von Strukturen muss das Zielsystem berücksichtigt werden, welches Alignment es unterstützt. Unter TwinCAT 3 sind entsprechende Attribute nutzbar {attribute 'pack_mode':= '0'}.
Das Interface besteht aus der Kommunikation mit dem Interface und den bis zu 32 CAN-Nachrichten. Die Inputs können nur gelesen werden die Outputs beschrieben werden.
Das Interface wird wie folgt angesprochen:
Outputs.TxCounter wird +1 gesetzt, wenn Daten gesendet werden sollen. Wie viele Nachrichten aus dem Buffer gesendet werden sollen, wird im NoOfTxMessages mitgeliefert. Der RxCounter zeigt an ob Daten neu im Buffer liegen. Wie viele Daten neu im Buffer liegen wird mit NoOfRxMessages übergeben.
Haben Sie die Daten abgeholt, so setzen Sie den Outputs.RxCounter:=Inputs.RxCounter. Damit weiß das CAN-Interface, dass es den Buffer erneut Füllen kann. Es müssen immer alle Daten ausgelesen werden, da das CAN Interface wieder alle Message Strukturen füllt wenn es notwendig ist.
Beispiel-Code zum Senden
if (Outputs.TxCounter = Inputs.TxCounter) // check if the interface is ready
and NumberOfMessagesToSend >0 then // and messages are to send
for i:=0 to NumberOfMessagesToSend-1 do // LOOP for copying the CAN message to the
// interface
Outputs.TxMessage[i] := MessageToSend[i]; // copy
End_for
Outputs.NoOfTxMessages := NumberOfMessagesToSend; // number of CAN messages you are going to send
Outputs.TxCounter := Inputs.TxCounter + 1; // inc. shows the CAN interface that new data
// is available and to send this data
end_if
Beispiel-Code zum Lesen
if Outputs.RxCounter <> Inputs.RxCounter then // check if new data is in the buffer
for i := 0 to (Inputs.NoOfRxMessages-1) do // start the LOOP and check how much data
// is in the buffer
MessageReceived[i] := Inputs.RxMessage [i]; // copy the CAN message
End_for
Outputs.RxCounter := Inputs.RxCounter; // set equal: the CAN interface then knows,
// that you have copied the CAN data
end_if
Message-Struktur bei Verwendung des 11 Bit Identifiers
Die Message-Struktur bei Verwendung des 11 Bit Identifiers besteht aus der COB ID [2 Byte] und den 8 Byte Daten. Die COB ID ist wie folgt aufgebaut:
- Bit 0-3: Länge der Daten (0…8)
- Bit 4: RTR
- Bit 5-15: 11 Bit-Identifier
Da beim 11 Bit Identifier COB ID, Länge und RTR Bit in einem Wort kodiert sind ist folgendes Beispiel hilfreich um die Daten aus dem Wort zu decodieren. Legen Sie sich hier eine Struktur an, um die dekodierten Daten in dieser Abzulegen.
IF RXCounter_Out <> RXCounter_In THEN
FOR I := 0 TO (NoOfTxMessages-1) DO
stCANInterfaceMessageValue[i].Lengh:=WORD_TO_BYTE(stCANInterfaceMessage[i].CobID) AND 16#0F;
stCANInterfaceMessageValue[i].RTR:=stCANInterfaceMessage[i].CobID.4;
stCANInterfaceMessageValue[i].CobID :=ROR(stCANInterfaceMessage[i].CobID,5) AND 16#07FF;
stCANInterfaceMessageValue[i].Data := stCANInterfaceMessage[i].Data;
CASE stCANInterfaceMessageValue[i].CobID OF
16#318: COB318:=COB318+1;
16#718: COB718:=COB718+1;
16#1CD: COB1CD:=COB1CD+1;
memcpy(ADR(TempValue),ADR(stCANInterfaceMessage[i].Data[6]),2);
16#1ED: COB1ED:=COB1ED+1;
ELSE
COBALLOther:=COBAllOther+1;
END_CASE
End_for
RXCounter_Out:=RXCounter_In;
END_IF
Message-Struktur bei Verwendung des 29 Bit Identifiers
Die Message-Struktur bei Verwendung des 29 Bit Identifiers besteht aus der Länge [2 Byte] der COB ID [4 Byte] und den 8 Byte Daten.
Lenght: Länge der Daten (0…8)
Die COB ID ist wie folgt aufgebaut:
- Bit 0-28: 29 Bit Identifier
- Bit 30: RTR
- Bit 31:
- 0: 11 Bit-Identifier,
- 1: 29 Bit Identifier