mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik CAN-USB SJA1000T <-> AT90CAN128


Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Ziel ist es ein CAN-Board (1) AT90CAN128 über ein Flachbandkabel 
(mit 120 Ohm an jedem Ende zwischen CAN_H und CAN_L) mit einem CAN-USB 
SJA1000T Adapter (2) anzusteuern

Ich kann keine Nachricht vom PC aus versenden, weder mit angeschlossenem 
noch mit abgehängtem CAN-Board (1).

Der CAN-USB (2) Adapter zeigt mit seiner roten LED immer einen 
BUS-Fehler an sobald ich versuche zu senden.

Auf dem CAN-Board läuft ein selbstgeschriebender Code (3). Die 
konfiguration des SJA1000T ist BRT0 = 04; BRT1 = BA;

Ich suche seit 2 Wochen den Fehler und komme nicht mehr weiter, die 
Forensuche liefert interessantes aber leider nichts passendes. Der 
Händler verweist mich auf den Entwickler, der Entwickler hat mir noch 
nicht antworten können.

(1) http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
(2) http://elmicro.com/files/lawicel/canusb_manual.pdf
(3)
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "avr/wdt.h"

void LedInit () {
  DDRE = 0x10;
  PORTE = 0x00; /*Die Logik der LED ist invertiert 0=AN*/
}

ISR ( CANIT_vect )
{
  cli(); /* Interrupts abschalten */
  if (PORTE == 0xFF){PORTE = 0x00;}
      else {PORTE = 0xFF;};

  
  /*Reset the Object for further use - wir wissen dass es objekt 1 war*/
  CANCDMOB = 0x88; /* Empfang und DLC 8 Byte */
  CANIDT4 = 0x00; /*RTRTAG, RB0TAG*/
  CANIDT3 = 0x00; /*Initialized for compatibility Reasons, does nothing*/
  CANIDT2 = (uint8_t) (0x124 << 5); // 0001 0010 0(100 X XXXX)  
  CANIDT1 = (uint8_t) (0x124 << 3); // (0001 0010 0)100
  for ( uint8_t i_msg = 0; i_msg < 8 ; i_msg++){
      CANMSG = 0x00; /* Messageobjekt löschen */
      /* Der µC inkrementiert INDX automatisch. 
      Im übertragenen Sinn enthält 
      CANMSG[INDX] die Nachrichten.
      CANPAGE:3 enthält NOT(AINC)*/
    }
  sei(); /* Interrrupts einschalten */
}

void CanInit ()
{
    CANGCON = 0x01 ; /* Reset CAN interface */
  CANGIE = 0x00; /* CAN interrupts zunächst aus */
  
// Disable Message Objects
    for ( uint8_t i_mob = 0; i_mob < 15; i_mob++ ) {
    /* Select the right MOB-Page */
    CANPAGE = i_mob << 4 ;
    /* Reset and Disable MOB */
    CANSTMOB = 0; //Status Register
    CANCDMOB = 0; //Control Register
    CANIDT1 = 0x00; //IDT
    CANIDT2 = 0x00; //IDT
    CANIDT3 = 0x00; //IDT
    CANIDT4 = 0x00; //IDT
    CANIDM4 = 0x00; //Maske
    CANIDM3 = 0x00; //Maske
    CANIDM2 = 0x00; //Maske
    CANIDM1 = 0x00; //Maske
    for ( uint8_t i_msg = 0; i_msg < 8 ; i_msg++){
      CANMSG = 0x00; /* Messageobjekt löschen */
      /* Der µC inkrementiert INDX automatisch. 
      Im übertragenen Sinn enthält 
      CANMSG[INDX] die Nachrichten.
      CANPAGE:3 enthält NOT(AINC)*/
    }
    
  }
/* Initialiesieren von MOB-PAGE 1 auf Empfang*/
  CANPAGE |= 1 << 4 ; /* MOB-Page 1 auswählen */
  CANCDMOB = 0x88; /* Empfang und DLC 8 Byte */
  CANIDT4 = 0x00; /*RTRTAG, RB0TAG*/
  CANIDT3 = 0x00; /*Initialized for compatibility Reasons, does nothing*/
  CANIDT2 = (uint8_t) (0x124 << 5); // 0001 0010 0(100 X XXXX)  
  CANIDT1 = (uint8_t) (0x124 << 3); // (0001 0010 0)100
  CANIDM4 = 0x00; /*RTRMSK, IDEMSK*/
  CANIDM3 = 0x00; /*Initialized for compatibility Reasons, does nothing*/
  CANIDM2 = (uint8_t) (0x7F0 << 5); // 0111 1111 0(000 X XXXX) 
  CANIDM1 = (uint8_t) (0x7F0 << 3); // 0(111 1111 0)000
    /* Resulting Span
    Mask 0x7F0 111 1111 0000
    IDT  0x124 001 0010 0100
    Results in
    First IDT 001 0010 0000 = 0x120
    Last IDT 001 0010 1111 = 0x12F */

/* General Interrupt Mask*/
CANGIE = 0xA0;
/* MOB Interrupt Mask*/
CANIE2 =0x02;
CANIE1 =0x00;
/*Set Bit Timing BPR 4, PRS 6, PHS1 3, PHS2 3, SJW 0 */
CANBT1 = 0x08;
CANBT2 = 0x0C;
CANBT3 = 0x37;

    // Start CAN interface

    CANGCON = _BV(ENASTB) ;

      // (Active wait!!) Wait until the CAN interface is ready

    while ( !( CANGSTA & ( 1 << ENFG ) ) ) ;
}

void InitDevices(){
cli(); /* Interrupts aus */
MCUSR = 0;
wdt_disable();  //Watchdog abschalten
CanInit (); /* CAN initialisieren */
LedInit();
sei(); /* Interrupts ein */
}

int main(void) 
{  InitDevices();
  while(1){}
  return 0;
}


Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein anderer Testaufbau:

Ich habe auf dem Can-Board von oben den Code aus 
Beitrag ""Hello World" für CAN mit AT90CAN in C"
CAN_Hello_World.zip
laufen mit der einzigen Änderung 8MHz in dem config header.

Wenn der Adapter der einzige Knoten am Bus ist oder er in der Luft hängt 
erhalte ich folgenden Fehler:
"BUS_ERROR"

Wenn das AT90USB128 Board am Bus hängt erhalte ich
"BUS_ERROR"
"ERROR_WARNING"
"ERROR_PASSIVE"

Was kann ich noch tun?
Ich muss meine Diplomarbeit abschließen und es klappt einfach nichts 
mehr.

Gibt es eine Mindestlänge für den CAN-BUS?
Mein Flachbandkabel ist 10 cm lang, auf jeder Seite hängen 120 Ohm 
zwischen CAN_H und CAN_L.

Welche Ursachen kann "BUS_ERROR" haben?

Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe einen weiteren CANUSB Adapter gekauft:
http://elmicro.com/files/lawicel/canusb_manual.pdf
der gleiche Fehler.

Hat jemand Ideen für weitere grundsätzliche Test mit denen ich dem 
Fehler auf die Spur kommen kann?

Autor: madler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du nur einen Knoten hast, werden die gesendeten CAN-Nachrichten von 
niemanden bestaetigt, das wird Dein Adapter wohl als Fehler melden.
Da ich keinen Deiner Adapter kenne, kann ich Dir aber nicht sagen, was 
es genau fuer eine Meldung gibt.

Wenn Du einen zweiten Adapter ranhaengst, musst Du in diesem auch 
konfigurieren, das er die von Dir gesendeten Pakete akzeptiert und 
bestaetigt (acceptance mask heisst das oft).

Das Kabel kann nicht zu kurz sein. Wenn Du Sorgen hast wegen der 
Uebertragung schalte doch auf zB 100KBit/s um.

Ansonsten wuerde ich empfehlen mal mit einem Oszi auf dem Bus zu 
lauschen, was dort zu sehen ist (insbesondere ACK-Slot), erklaert Dir zB 
der wikipedia-Artikel zu CAN.

Autor: Johannes H. (kuriboh)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich komme erst Mittwoch zu einem Oszi.

Ich habe meinen Code komplett überarbeitet und anhand von Beispielen 
einen neuen geschrieben der die AVR Biliothek verwendet.

Folgende zwei Knoten habe ich:
(1) http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
(2) http://elmicro.com/files/lawicel/canusb_manual.pdf

(1) AVR-CAN ist mit angefügtem Code versehen.
(2) canusb ist mit 100 kBit an den Bus angeschlossen.

Das Experiment funktioniert nun genau anders herum:
Einmal pro Sekunde sendet Knoten (1) eine Nachricht und Toggelt seine 
LED
Knoten 2 soll die Nachricht empfangen. Am PC sehe ich keine Nachrichten.

Hat jemand einen AT90CAN128 zur Hand und kann den Code in einem anderen 
CAN Aufbau testen?
AT90CAN128, FOSC 16 MHz, CAN_BAUDRATE 100 kBit/s, Eine LED an PE4

Autor: Johannes H. (kuriboh)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich fühle mich als ob ich keinen Ansatzpunkt mehr habe. Ich habe 
mittlerweile alle Beiträge die AT90CAN im Betreff haben durchgelesen und 
erkenne das Problem nicht.

Ich habe noch ein Minimalbeispiel geschrieben.
Diesmal soll der USBAdapter irgendwas an den AT90CAN senden. Wieder 
BUS_ERROR beim Senden auf Seite des USBAdapters. Zur Sicherheit poste 
ich das Minimalbeispiel, morgen Abend baue ich ein neues Kabel...

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schon erwähnt wurde muss in einem CAN Bus neben der sendenden Node 
noch eine weitere empfangsbereite Node sein, sonst gibt es mit 
Sicherheit einen Bus Error, weil das ACK Bit nicht gesetzt wird. 
Allerdings setzt jede Node, die den Frame als korrekt ansieht, dieses 
Bit. Nicht nur diejenige, die sich dafür auch inhaltlich interessiert. 
Filter sind hierbei also nicht relevant.

Wenn in einer korrekten CAN Verdrahtung bei gleicher Bitrate stets ein 
Bus Error auftritt, dann kommt man nicht umhin, sich das Signal mal 
anzusehen.

Hier sieht es aber eher so aus, als ob der AVR nicht wirklich am Bus 
teilnimmt, oder mit der falschen Rate.

Autor: Harald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundsätzlich solltest Du mal einen Test machen, ob es mit einer 
fertigen CAN-Library funktioniert:
http://www.kreatives-chaos.com/artikel/universelle...

Ich habe diese LIB mal für einen AT90CAN128 angewendet, sie funktioniert 
hervorragend und auf Anhieb.

Du solltest Dir schnellstens Zugang zu einem digitalen Scope verschaffen 
(sollte kein Problem sein, wenn das deine Diplomarbeit ist), dann kannst 
Du die reale Bitrate ausmessen. Alternativ mit dem PC-Tool mal alle 
Bitraten durchgehen, vielleicht kommt man so auf den Fehler.

Autor: madler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm. Habe gerade mal ueber Deinen Code (09CAN_TRY_ACK) geschaut, sieht 
ja eigentlich gut aus.
Ich bekomme meine CAN128 Platine leider erst Ende des Monats...

Nur nicht aufgeben, es liegt bestimmt an etwas ganz bloedem.
Du solltest jetzt Schritt fuer Schritt vorgehen und da wuerde ich auf 
der untersten Ebene anfangen, dh mal das Oszi dranhalten.
Sendet der CAN128 mit Deinem/dem HelloWorld-Testprogramm, kommts am 
richtigen Pin am CAN-Adapter an, stimmt die Baudrate, etc? Dann ev die 
andere Richtung. Wenn das Senden mit dem CAN128 dann klappt sollte auch 
empfangen klappen.

Nochmal zum Verstaendnis: Was meintest Du oben mit "8MHz in dem config 
header" umgeaendert? Alle Hardware und Beispiele haben und brauchen doch 
16Mhz oder?
Und hast Du jetzt zwei CAN-Adapter (und den CAN128) oder nur einen?
Hast Du mal die Pin-Belegung des CAN-Adapters irgendwo ueberprueft, ich 
sehe die im PDF nirgendwo.

Autor: Plan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil Du ja jetzt noch kein Oszi hast, Du kannst ja mal LEDs an die Rx Tx 
Pins an schließen. Dann siehst Du wenigstens ob ein Telegramm raus 
geht...

Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ madler, Ich glaube Du hast Da was wichtiges aufgestöbert. Ich habe 
laufend vorausgesetzt dass die Schnittstelle genormt ist. Es scheint mir 
als ob das Olimex Board falsch verbunden ist.

Standard http://www.interfacebus.com/Can_Bus_Connector_Pinout.html
canusb http://www.canusb.com/products.htm
AVR-CAN http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
@ madler, Ich glaube Du hast Da was wichtiges aufgestöbert. Ich habe 
laufend vorausgesetzt dass die Schnittstelle genormt ist. Es scheint mir 
als ob das Olimex Board falsch verbunden ist.

Standard http://www.interfacebus.com/Can_Bus_Connector_Pinout.html
canusb http://www.canusb.com/products.htm
AVR-CAN http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
  Standard   canusb          AVR-CAN
1 Reserved   12V / 5V / nc   NC
2 CAN_L      CAN_L           TXD0
3 CAN_GND    CAN_GND / nc    RXD0
4 Reserved   nc              NC (not connected through R14 to pin 6)
5 CAN_SHLD   nc              GND 6 NC (not connected through R14 to pin 4)
6 GND        CAN_GND / nc    NC (not connected through R13 to pin 8)
7 CAN_H      CAN_H           NC (not connected through R13 to pin 7)
8 Reserved   nc              NC (not connected through R13 to pin 7)
9 CAN_V+     12V / 5V / nc   NC
Danke für all die Tips, ich werde das Heute durchprobieren.
-Verbindungen im Olimexboard durchmessen
-physikalische Verbindeung erneuern
-LEDs and den Bus hängen
-Den CAN Status mit LEDs herausleiten
-Die CAN Bibliothek verwenden (universelle-can-bibliothek)

Um einige offenen Fragen zu beantworten:
8MHz waren falsch, das CAN-Board ist mit externen 16 MHz getaktet. Ich 
mache das mittlerweile richtig, sollte auch in der 09CAN_TRY_ACK richtig 
enthalten sein.

Insgesamt habe ich folgende Hardware zuhause:
Drei mal http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
Zwei mal http://elmicro.com/files/lawicel/canusb_manual.pdf

EDIT: Postingfehler

Autor: pcb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schaue doch eine halbe Seite im Datenblatt tiefer:
  Standard | canusb        | AVR-CAN:     ABER!!   AVR-CAN: CAN
                              RS232 Buchse:    |   CAN Stecker:
1 Reserved   12V  5V  nc     NC                     NC
2 CAN_L      CAN_L           TXD0                   CANL
3 CAN_GND    CAN_GND / nc    RXD0                   GND
4 Reserved   nc              NC                     NC
5 CAN_SHLD   nc              GND                    NC  
6 GND        CAN_GND / nc    NC                     GND
7 CAN_H      CAN_H           NC                     CANH
8 Reserved   nc              NC                     NC
9 CAN_V+     12V  5V  nc     NC                     VIN

Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, Wunschdenken...
Ich habe mich über das falsch verbundene so gefreut - ich hatte es aus 
dem RS232 übernommen... Hier die richtige Tabelle (Editierberechtigt zum 
obigen Post bin ich wohl nicht mehr.

Standard http://www.interfacebus.com/Can_Bus_Connector_Pinout.html
canusb http://www.canusb.com/products.htm
AVR-CAN http://www.olimex.com/dev/pdf/AVR/AVR-CAN.pdf
  Standard   canusb          AVR-CAN
1 Reserved   12V / 5V / nc   NC
2 CAN_L      CAN_L           CANL
3 CAN_GND    CAN_GND / nc    GND
4 Reserved   nc              NC
5 CAN_SHLD   nc              NC
6 GND        CAN_GND / nc    GND
7 CAN_H      CAN_H           CANH
8 Reserved   nc              NC
9 CAN_V+     12V / 5V / nc   VIN

(EDIT: Ah, es gab gleich eine Antwort - darum nicht berechtigt ^^)

Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So,... Errorcodes habe ich mir noch nicht herausgelegt, aber:
1. Olimex CAN-AVR hat bereits einen eingebauten 120 Ohm Terminator. Ich 
hatte demnach grundsätzlich zuviele Endwiederstände im System.
2. Eine LED die zwischen CAN_L und CAN_H hängt geht in Dauerleuchten 
über wenn der Adapter versucht zu senden.
3. Eine LED die zwischen CAN_L und CAN_H hängt leuchtet gar nicht wenn 
der AVR-CAN versucht zu senden.

Ich vermute dass hier der Hund begraben ist.
Muss ich zu irgendeinem Zeitpunkt definieren WO genau die CAN Pins sind?

Autor: Johannes H. (kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Nur nicht aufgeben, es liegt bestimmt an etwas ganz bloedem."

Ich habe den Fehler gefunden, die meisten codes die ich geschrieben habe 
sind fehlerfrei. Problem war die Versorgungsspannung.

Das Olimex hat einen Versorgungsbereich von 5V bis 9V, da ich recht 
vorsichtig bin habe ich 5V eingestellt - vermutlich aus 
Messgenauigkeitsgründen waren das wohl real unter 5V. Ich bin auf 5V3 
hoch gegangen und sofort funktionieren meine Codes.

Für die Nachwelt, und um auch was beizutragen, werde ich für das 
Olimex-Board CAN-AVR AT90CAN128 vier Minimalbeispiele mit WinAVR in GCC 
erzeugen und hier posten. (Die Schlagwörter sind für Suche.)

1. Senden einer Nachricht auf Knopfdruck.
2. Empfang einer Nachricht über Interrupt.
3. Empfan einer Nachricht über Polling.
4. Antwort auf eine RTR Nachricht.

Ich bedanke mich für die Hilfe und bin offen für weitere 
Minimalbeispielvorschläge.

Autor: Johannes H. (kuriboh)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Aus Zeitgründen gehe ich doch direkt dazu über eine Bibliothek zu 
schreiben. Hier zwei funktionierende "Minicodes".

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.