mikrocontroller.net

Forum: Haus & Smart Home Fehler für Can_Bus


Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich programmiere mit dem Mikrocontroller at90can128 und versuche 
CAN_Felher zu behandeln. Ich möchte eine Meldung bekommen, wenn ich  z.B 
die CAN-Kabel ziehe.
Ich habe die folgende Funktion implementiert

#define CAN_BUS_OFF  0x00
#define CAN_PASSIVE  0x01
#define CAN_SUCCESS  0x02


int8_t AtCanGetBusState(void)
 {
   if (CANGSTA & (1<<BOFF))
     return CAN_BUS_OFF;
   if (CANGSTA & (1<<ERRP))
     return CAN_PASSIVE;
   return CAN_SUCCESS;
}
jetzt bekomme ich die Meldung nach dem ich die Kabel wieder eingesteckt 
habe.
Gibt es eine Möglichkeit diese Funktion in beliebige Zeit aufzurufen und 
nicht in eine bestimmte Stelle im main aufzurufen. Ich meine beim Laufen 
des Programms wird plötzlich die Kabel gezogen und in der Zeitpunkt 
bekomme ich die passende Rückgabe Wert.
Auf alle Hilfe bin ich sehr dankbar

Autor: Juergen Harms (harms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich glaube, dass einfach Bus-Kabel ziehen an sich von einem 
CAN-Controller noch nicht als Fehler empfunden wird. Das Problem kommt, 
wenn der Controller ein Meldung sendet und - weil das Kabel gezogen ist 
- niemand am Bus antwortet.

Vorschlag: miss die Zeit, zu der Meldungen zum Senden abgelegt werden 
(z.B. in einer Tabelle mit 15 Eintraegen, einem pro MOb) und, in Deiner 
Warteschleife, schau nach ob eine MOb "zu lange" schon eine gesendet 
werdende Meldung hat. Wenn ja, dann hast Du Deinen Fehler, und Du kannst 
diese Meldung loeschen.

"Zu lange" laesst sich aus der Bitrate und Reserven fuer Behandlung im 
Sender und Empfaenger abschaetzen. Ich verwende zu diesem Zweck das 
obere Bit des CAN Timers (CANTIMH), mein Timer laeuft mit 10 kBps (Bus 
Takt = 100kBps). Hier ist die Prozedur CanCheckWait, die ich in meiner 
Warteschleife periodisch aufrufe (wenn nichts zu tun ist, alle 10 msec - 
jedes Mal wird eine neue MOb geprueft)- meine Tabelle ist in 
can_status.cs_stamp (uint8_t):
// Check next MOB for send-hang
// ----------------------------
//  Consider an MOB as hanging if xmit is not terminated after > 75 msec
//
//  Return the MOB ordinal if the MOB hangs
//  Return -1 if the MOB is OK

int8_t CanCheckWait ()
{
    uint8_t    x_mob ;      // ordinal of MOB to check
    int8_t    x_wait ;

    static uint8_t  next_mob = 0 ;    // next MOB to check

      // Determine which MOB to check
      //  - the variable next_mob does a circular walk-trough { 0 .. 14 }
      //  - do nothing if the MOB is not transmitting

    if ( next_mob > 14 ) next_mob = 0 ;    // circular overflow modulo 14
    x_mob = next_mob++ ;
    CANPAGE = x_mob << 4 ;
    if ( ( CANCDMOB & _BV(CONMOB0) ) == 0 ) return -1 ; // OK if not sending

      // Check the time spent since the launch of the transmission:
      //  - cs_stamp is the value of CANTIMH at transmission launch,
      //  - the high byte of the CAN-timer (CANTIMH) has increments of
      //    25.6 msec (at 10kHz = 0.1 msec increments of CANTIML),
      //  - sampling jitter = 25.6 msec due to only considering CANTIMH.
      //
      // x_wait > 3 ... frame hold detection at 76.8 ... 102.4 mseconds

    x_wait = CANTIMH - can_status.cs_stamp[x_mob] ;
    if ( x_wait < 0 ) x_wait += 256 ;    // handle counter wrap-around
    if ( x_wait > 3 ) return x_mob ;
    return -1 ;
}

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo Juergen,
ich versuche deine Code zu verstehen und auch bei mir zu implementieren 
und melde ich mich wieder.
Ich danke Dir

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo juergen,
habe ich das Datenblatt über Timer/Counter gelesen, weil ich zum ersten 
mal damit beschäftige. In deiner code sehe ich nicht wo Du die Register 
für Timer/Counter gesetzt hat. Wie wählst Du das Timer? Im Datenblatt 
steht dass CANTIML bzw CANTIML nur Leseregister sind.Du sagst, dass Du 
obere Bit des CAN Timers (CANTIMH) verwendest. Außerdem verstehe ich 
diese Zeile: x_wait = CANTIMH - can_status.cs_stamp[x_mob] ;
Bitte kannst Du mir noch einmal mehr Eklärungen geben. Wie muss ich 
zuesrt das Timer setzen?

Ich danke Dir

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn der Controller sendet und kein ACK bekommt, geht der erstmal 
von

ACTIVE nach ERROR_PASSIVE. Das kann man sich auch mit einem IRQ in einer 
Variablen signalisieren lassen und dann per Vergleicher in der Mainloop, 
eine Änderung detektieren. Dann sollte man in jedem Fall mitbekommen, 
wenn man
vom CAN "abgekoppelt wird". Das schöne ist, dass wenn man das Kabel 
wierder einsteckt, nach einer gewissen Anzahl fehlerfreier Nachrichten, 
der Zustand automatisch wider in den ACTIVE geht.

Autor: Juergen Harms (harms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da habe ich es mir vielleicht etwas leicht gemacht: ich hatte 
verstanden, das der Zustand von ACTIVE nach ERROR_PASSIVE kippt, wenn es 
zufolge IRGENDEINES Fehlers 127mal schief geht, und das als "zu 
kompliziert" links liegen lassen - mein Hauptproblem war, nach 
haengengebliebenen MObs zu fischen. Muss ich mir genauer anschaun.

Zur urspruenglich gestellten Frage: zum Erkennen des Fehlers ist das 
einfacher - aber was geschieht mit dem MOb das der Kontroller nicht los 
wird? - Deine Wahl.

Antwort zu den spezifischen Fragen. Geh zum Artikel in 
http://www.mikrocontroller.net/articles/CAN_Bibili...
und hole Dir in den Links am Ende die Dateien Can.c und Can.h. Suche 
darin nach can_status.cs_stamp - das zeigt Dir wie diese Variable 
gehandhabt wird ( und wie sie beim Senden eines Frames gesetzt wird). In 
CanInit siehst Du wie CANTCON initialisiert wird - das bestimmt den Takt 
fuer CANTIM, CANTIMH und CANTIML laufen dadurch "von selber". Die Zeile 
mit xmit_wait: sie rechnet die abgelaufene Zeit seit dem Senden aus. In 
can_status.cs_wait liegt der Zeitpunkt (CANTIMH Einheiten) beim Senden, 
das wird mit dem momentanen Wert von CANTIMH verglichen 
(ueberlauf-behandelt) und ergibt "wie alt" der Sendeprozess ist - und 
can_status.cs_stamp ist eine Tabelle, indiziert mit dem MOb Index.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.