Forum: Mikrocontroller und Digitale Elektronik CAN Bus off AtmegaxxM1


von Klemmen (Gast)


Lesenswert?

Hallo,

ich habe folgendes Problem:

Ich nutzte einen AtmegaxxM1 um über den CAN Bus zu kommunizieren.

Hierbei kann es vorkommen, dass ein Gerät nicht am Bus hängt, aber 
trotzdem laufen soll. Der Bootloader auf diesem Gerät sendet mir zu 
beginn eine "Hallo ich bin da" Nachricht aus dem Bootloader heraus. Dies 
ist wichtig und kann nicht drauf verzichtet werden.

Das Problem ist, wenn ich nun das Gerät trenn und dann reset oder 
starte, bleibt er beim senden der ersten "Hallo hier bin ich" Nachricht 
hängen, weil der Bus nicht vorhanden ist.

Im Datenblatt steht, dass im Register CANGSTA BOFF eine 1 steht, wenn 
der Bus off ist. Dh. ich könnte das senden ja abbrechen, sobald BOFF 
nicht NUll ist. Das funktioniert aber leider nicht.

if(!(CANGSTA & 0b00000010)) {
// Senden }
else {
// nicht senden
}

Ich frage mich daher, wann genau das BOFF Bit gesetzt wird, wenn der BUS 
off ist. Ich werde aus dem Dateblatt nicht schlau.

Wie kann ich es hinbekommen, dass er das senden aufgibt, wenn kein Bus 
vorhanden ist?

von Rolf M. (rmagnus)


Lesenswert?

Klemmen schrieb:
> Ich nutzte einen AtmegaxxM1 um über den CAN Bus zu kommunizieren.

Hmm, einen µC mit dem Namen finde ich bei Microchip nicht.

> Im Datenblatt steht, dass im Register CANGSTA BOFF eine 1 steht, wenn
> der Bus off ist. Dh. ich könnte das senden ja abbrechen, sobald BOFF
> nicht NUll ist. Das funktioniert aber leider nicht.

Kannst du nicht einfach abbrechen, wenn du deine "hallo"-Nachricht 
rausgeschickt hast? Wenn die nicht gesendet werden kann, gibt's halt 
Error-Frames und dann das Bus-off, aber worauf wartet dein Code dann?

PS:
> CANGSTA BOFF

Klingt wie der Name eines Rappers :)

von Klemmen (Gast)


Lesenswert?

Rolf M. schrieb:
> PS:
>> CANGSTA BOFF
>
> Klingt wie der Name eines Rappers

Hab auch erstmal nach den Registern gegoogelt. Da wird dir genau sowas 
als Ergebnis angezeigt :-).

von Klemmen (Gast)


Lesenswert?

Ich umschreibe es nochmal etwas anders

Wenn ich die Interrupts aktiviere:
CANGIE = ( 1 << ENIT ) | ( 1 << ENBOFF) | ( 1 << ENRX ) | ( 1 << ENTX ) 
| (1 << ENERR) | (1 << ENBX) | (1 << ENERG);

Sollte ja wenn die generellen Interrupts aktiv sind, beim Trennen des 
Kabels ein BOFF Interrupt gesetzt werden.

Wenn ich dann in der Interrupt Routine folgendes abfrage:
1
ISR (CAN_INT_vect) {
2
  if(CANGSTA & (1 << BOFF)) {
3
    PORTB |= 1 << PORTB6;
4
  }
5
  else if(CANGSTA & (1 << ERRP)) {
6
    PORTB |= 1 << PORTB6;
7
  }
8
  else if(CANGIT & (1 << BOFFIT)) {
9
    // BUS OFF
10
    PORTB |= 1 << PORTB6;
11
...

Sollte doch die LED, die an PORTB6 angeschlossen ist, angehen. Tut Sie 
aber nicht.

Würde mich freuen, wenn mir jemand einen Tipp gibt.

von Rolf M. (rmagnus)


Lesenswert?

Klemmen schrieb:
> CANGIE = ( 1 << ENIT ) | ( 1 << ENBOFF) | ( 1 << ENRX ) | ( 1 << ENTX )
> | (1 << ENERR) | (1 << ENBX) | (1 << ENERG);

Behandelst du diese sämtlichen Interrupt-Quellen denn auch alle korrekt? 
Sonst würde ich erst mal alles abschalten, was nicht behandelt wird.

Und löschst du entsprechend Datenblatt die Interrupt-Flags?
====================
To acknowledge a MOb interrupt, the corresponding bits of CANSTMOB 
register (RXOK, TXOK,...) must be cleared by the software application. 
This operation needs a read-modify-write software routine.
To acknowledge a general interrupt, the corresponding bits of CANGIT 
register (BXOK, BOFFIT,...) mustbe cleared by the software application. 
This operation is made writing a logical one in these interrupt 
flags(writing a logical zero doesn’t change the interrupt flag value).
====================

Wenn du das nicht tust, bleibt die Interrupt-Bedingung bestehen, und 
beim ersten CAN-Interrupt, der auftritt, wird die ISR immer und immer 
wieder als Endlosschleife aufgerufen.

: Bearbeitet durch User
von Klemmen (Gast)


Lesenswert?

Im Grunde sind es nur die Register
CANGIT (CANIT, BOFFIT, BXOK, SERG, CERG, FERG AERG)
CANGSTA ( BOFF und ERRP )
CANSTMOB ( TXOK und RXOK)

Die Prüfe ich auf Interrupt, der schlägt aber nicht aus.

Ich verstehe auch den Sinn von BOFF und BOFFIT nicht. Wenn der Bus off 
ist, sollte ja der Interrupt BOFFIT auslösen und im Statusregister BOFF 
auf eins gesetzt werden. Würde es nicht reichen, wenn man nur das BOFFIT 
ausliest? Oder ist das gedacht, wenn man pollen will? Das man dann das 
BOFF liest?

Deinen Vorschlag alle zum testen unwichtigen Interrupts zu deaktivieren, 
werde ich testen. Danke fürs den Tipp.

von Rolf M. (rmagnus)


Lesenswert?

Klemmen schrieb:
> Im Grunde sind es nur die Register
> CANGIT (CANIT, BOFFIT, BXOK, SERG, CERG, FERG AERG)
> CANGSTA ( BOFF und ERRP )
> CANSTMOB ( TXOK und RXOK)
>
> Die Prüfe ich auf Interrupt, der schlägt aber nicht aus.
>
> Ich verstehe auch den Sinn von BOFF und BOFFIT nicht. Wenn der Bus off
> ist, sollte ja der Interrupt BOFFIT auslösen und im Statusregister BOFF
> auf eins gesetzt werden. Würde es nicht reichen, wenn man nur das BOFFIT
> ausliest?

BOFFIT ist das Interrupt-Flag. Das wird gesetzt, wenn der CAN-Controller 
in den Zustand "Bus off" wechselt. Wenn diese Flag und das globale 
Interrupt-Flag  gesetzt sind, springt der µC bei der nächsten 
Instruktion in die ISR. Da muss dann Code von dir stehen, mit dem du den 
Interrupt verarbeitest und dann (wichtig!) das Flag wieder löschst. Mit 
dem Löschen deaktivierst du nicht den Zustand "Bus off", sondern nur die 
Bedingung für den Interrupt. Wenn du das nicht machst, springt der µC 
nach Abarbeitung deiner ISR gleich wieder rein, weil das Flag ja immer 
noch gesetzt ist. Und das gilt für die Flags sämtlicher Interrupts, die 
du aktiviert hast.
BOFF dagegen kann man gar nicht schreiben. Es enthält immer die 
Information darüber, ob der µC gerade im Zustand "Bus off" ist oder 
nicht.

> Deinen Vorschlag alle zum testen unwichtigen Interrupts zu deaktivieren,
> werde ich testen. Danke fürs den Tipp.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.