Hallo zusammen,
ich versuche gerade einmal die CAN-Schnittstelle auf einem AT90CAN ans
Laufen zu bekommen. Habe den mal gewählt, weil da schon ein
CAN-Controller drin ist. Senden und empfangen von Nachrichten
funktioniert eigentlich soweit auch ganz gut.
Ich möchte mich jetzt ein wenig daran wagen, die CAN-Fehler zu erkennen,
zumindest teilweise.
Vielleicht erst einmal, was ich bisher gemacht habe:
Ich frage mit folgendem Code die Fehlerregister aus und schicke die
Daten der UART an einen PC zur Kontrolle. Das funktioniert auch.
1 | while(1)
|
2 | {
|
3 | _delay_ms(1000);
|
4 | can_send(&message);
|
5 | errortx = CANTEC;
|
6 | errorrx = CANREC;
|
7 | itoa(errortx,send, 10);
|
8 | uart_puts(send);
|
9 | itoa(errorrx,send, 10);
|
10 | uart_puts(send);
|
11 | ...
|
12 | }
|
Mit dem folgenden Codeausschnitt frage ich den Errror Passiv Status ab:
1 | if (CANGSTA & (1 << ERRP))
|
2 | {
|
3 | // Do something....LED on or something like that
|
4 | CANGSTA &= ~(1 << ERRP);
|
5 | }
|
Der Bus Off Status soll per Interrupt überwacht werden. Also wenn der
Controller in den Bus OFF Status geht, kommt der Interrupt und man kann
entsprechend handeln.
1 | // Interrupt-Service-Routine für die Fehler
|
2 | ISR(CANIT_vect)
|
3 | {
|
4 | if (CANGSTA & (1 << BOFF))
|
5 | {
|
6 | // Do something....LED on or something like that
|
7 | CANGSTA &= ~(1 << BOFF);
|
8 | }
|
9 | }
|
Mit Folgendem werden die Interrupts beim Initialisieren des CAN
eingeschaltet:
1 | CANGIE = (1 << ENIT) | (1 << ENRX) | (1 << ENTX) | (1 << ENBOFF) | (1 << ENERR);
|
Meine Frage wäre nun, wie ich das Ganze testen kann.
Wenn ich das Programm laufen lasse und am anderen Ende keinen weiteren
Teilnehmer dran hänge, springt der Controller direkt in den Error
Passive Mode, das Transmit-Error-Register steht auf 128 und bleibt auch
da stehen, lasse mir das ja über UART ausgeben. Schließe ich nun einen
anderen Teilnehmer am anderen Ende an, kommen dort die weiteren
Nachrichten auch an, denn die while-Schleife läuft ja weiter und der
Wert des Transmit-Error-Registers CANTEC zählt rückwärts, wie gewünscht.
Da die While-Schleife ja weiter läuft, versucht der Sender immer weiter
zu senden. Da am anderen Ende kein Teilnehmer hängt, also kein
Acknowledge kommt, verscuht er immer weiter zu senden, aber erhöht den
Transmit-Error-Registers CANTEC nicht. Das ist in der Spezifikation ja
so vorgegeben.
Meine Frage wäre nun, wie ich Fehler auf dem Bus so erzeugen kann, dass
ich mal einen Bus-Off-Status provozieren kann, um zu sehen, ob der
entsprechende Interrupt auch funktioniert?
Meine zweite Frage wäre, warum das Transmit-Error-Registers CANTEC
direkt auf 128 springt, wenn er merkt , dass niemand antwortet? Wenn ich
das Programm sterte, wird ein erstes mal gesendet. danach ja direkt das
Fehlerregister ausgelesen und da steht es direkt auch 128. Ich dachte,
dass würde auch raufgezählt; in 8er Schritten eigentlich, wenn ich das
richtig verstanden habe.
Als letztes vielleicht noch die Frage, was man allgemein bei
festegestellten Fehlern macht. Beim Buss-off-Status ist klar, da muss
erst einmal resettet werden. Macht es Sinn, die ganzen anderen Fehler
wie Bit-Stuffing usw. für eine 08/15 CAN Kommunikation abzufragen. Ich
will ja keine kritischen Daten versenden, bzw. wie würde man
Softwaremäßig bei einem Fehler reagieren oder das einfach automatsich
der Hardware überlassen. Die verschiedenen Error-Modes werden ja auch so
erreicht.
In diesem Bereich, also wie man da genau mit den zahlreichen
Fehlermöglichkeiten umgeht sind bei mir halt noch so einige Fragen
offen.
Vielleicht kennt sich der ein oder andere ja ein wenig besser mit CAN
aus und kann ein paar Informationen oder Anregungen zur Diskussion
geben.
Ich bedanke mich schonmal!
Beste Grüße ins Forum
Thomas