Hallo, ich nutze einen Atmega16M1. Zumeist verwendet ich CAN. Es kann aber auch sein, dass ein Knoten getrennt wird, seine Arbeit aber weiter verrichten soll. Dh. der Knoten ist vom Bus getrennt, es kann aber sein, dass er versucht Nachrichten auf den Bus zu schicken. Wenn er dies tut, bleibt er hängen. Sobald ich den Bus wieder verbinde geht es weiter. Nun ist meine Frage, wie kann ich erkennen, ob der Bus gerade OFF ist, sodass erst garnicht versucht wird, eine Nachricht zu senden. Im Register CANGSTA gibt es das BOFF Bit. Wenn ich aber vor senden folgendes prüfe: if (CANGSTA & ( 1 << BOFF) == 0 { // senden } Versucht er trotzdem zu senden. Merkt er erst das der Bus off ist, wenn er versucht hat zu senden? Wie kann ich hier rangehen um mein Problem zu lösen?
Ich habe jetzt eingestellt, dass der BUSSOFF Interrupt EN ist. CANGIE = ( 1 << ENIT ) | (1 << ENBOFF) | ( 1 << ENRX ); Und die ISR sieht so aus:
1 | ISR (CAN_INT_vect) { |
2 | |
3 | // if (CANGIT & (1 << CANIT)) { |
4 | // PORTB |= (1 << PORTB6); |
5 | // } |
6 | if(CANGIT & (1 << BOFFIT)) { |
7 | CANGIT |= (1 << BOFFIT); |
8 | PORTB |= (1 << PORTB6); |
9 | } |
10 | else if (CANGSTA & (1 << BOFF)) { |
11 | PORTB |= (1 << PORTB6); |
12 | } |
13 | else if (CANGSTA & (1 << ERRP)) { |
14 | PORTB |= (1 << PORTB6); |
15 | } else { |
16 | // senden |
17 | } |
18 | } |
An PB6 ist eine LED. Trenne ich das Gerät vom Bus, geht die LED aber nicht an. (LED funktioniert im sonstigen Programmablauf)
Program schrieb: > Trenne ich das Gerät vom Bus, geht die LED aber > nicht an. BUS-OFF bedeutet nicht, dass das Gerät einfach nur getrennt ist. Es bedeutet, dass der CAN-Controller nach x Fehlern nicht mehr am Bus teilnimmt. Siehe auch zig Seiten mit CAN Grundlagen im Netz.
Wie kann ich den verhindern, dass mein Gerät versucht zu senden, obwohl es vom Bus getrennt ist. Oder ist das einfach nicht vorgesehen?
Lass ihn doch versuchen zu senden, stört doch nicht weiter. Nur hängen bleiben muss die Software dabei natürlich auch nicht.
1 | CANPAGE = (1<<4); // select MOB1 |
2 | if(CANSTMOB & (1<<TXOK)) // fertig mit Senden? |
3 | { |
4 | CANSTMOB &= ~(1<<TXOK); // reset flag |
5 | |
6 | CANMSG = 42; |
7 | CANMSG = can_counter++; |
8 | CANCDMOB |= (1<<CONMOB0); // Transfer einleiten |
9 | } |
Das kann man so oft aufrufen wie man will, ob der CAN nun angeschlossen ist oder nicht. Was man da drüber und drum herum natürlich noch machen kann ist zum Beispiel mit einem Timeout den CAN-Controller zu resetten.
Program schrieb: > Wie kann ich den verhindern, dass mein Gerät versucht zu senden, obwohl > es vom Bus getrennt ist. Oder ist das einfach nicht vorgesehen? Ist nicht so richtig vorgesehen. Wenn es aus Sicht des Systems ein Slave ist, könnte man mit dem Senden solange warten bis man dazu aufgefordert wird. Wenn man im Livebetrieb unterbricht gibt es halt für den Slave einen BUS-OFF - ist das schlimm? Ich denke nicht. Dann weiß der Knoten ja, dass da etwas faul ist und sich per LED oder sonstwie bemerkbar machen. Der Kommunikationsmaster muss natürlich als Erster senden und würde einen BUS-OFF hinlegen wenn keiner zuhört. Das ist dann aber ja gewissermaßen richtig. Auch hier wäre eine Fehleranzeige angebracht.
Oh ja, Tipp, ich habe zwar lange den ATMega16M1 benutzt, bin aber wegen CAN-FD auf die ATSAMC21 / ATSAME51 umgestiegen. Der ATSAMC21E18A-AU ist im gleichen Gehäuse wie der ATMega16M1-AU, kostet dabei aber weniger, läuft auch bei 5V, hat 256k FLASH, 48MHz und Peripherie ohne Ende.
Rudolph schrieb: > Der ATSAMC21E18A-AU Interessantes Teil, wie wird denn der programmiert? Habe gerade mal das Datasheet quergelesen, konnte mal eben schnell nichts finden.
Der hat SWD, dafür benutze ich die "SAM" Seite von dem Atmel ICE. Oder einen JLink Edu Mini wenn ich den ATSAM mit 3,3V betreibe. Im Kapitel 50.8.1 ist das zu sehen.
Nochmal zum nicht funktionierenden Bus: Wenn es keinen Bus gibt (oder auch keinen anderen Busteilnhemer, der am Ende die CAN-Nachricht bestätigt), dann gibt es für diese Nachricht kein TXOK. Das MOB wird damit auch nicht wieder frei zum Verschicken weiterer Nachrichten. Ich vermute, dass dein Code bei der Suche nach einem freien MOB hängen bleibt. Oder kurz danach, wenn keines gefunden wurde.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.