Hi, meine seltsamen Probleme wollen nicht abreissen... Also ich habe hier einen mega32 an dem ein sja1000 hängt. Ich kann ihn offensichtlich korrekt ansprechen, denn Konfigurationsregister des Controllers können von mir beschrieben werden und beim auslesen kommt auch wieder das raus, was ich vorher reingeschrieben habe. Nur das message versenden will einfach nicht klappen. Auf der anderen Seite hängt auch ein sja1000, der die Message angeblich korrekt empfängt. Der empfängt aber nur Kauderwelsch (erkennt aber trotzdem keinen Übertragungsfehler). Jetzt habe ich den sendenden Kontroller mit "self reception request" seine message selbst wieder empfangen lassen. Und sogar er selbst empfängt nur Kauderwelsch! Aber immerhin bitgenau den selben Kauderwelsch, den auch andere Kontroller auf dem Bus empfangen. Kann mir da wer nen Tipp geben? Timingprobleme bei der Ansteuerung des CAN Controllers kann ich ja ausschliessen, wegen der korrekten Funktion der Register. Aber wenn das Ding noch nicht mal seine eigene Message korrekt empfängt....
Bustreiber benutzt? Bus abgeschlossen? Kannst du mal den Schaltplan posten?
Versuch mal Pakete mit lauter 0x00 oder lauter 0xFF zu senden und schau ob Du von den Mülldaten irgendwie auf die echten Daten schließen kannst.
Vorneweg: Mir ist es gelungen eine Message korrekt zu senden und zu empfangen. Dennoch: Ich habe offensichtlich ein totales Brett vorm Kopf. Das Problem liegt in der Software bzw beim Compiler. folgender Code funktioniert NICHT und liefert immer die selben Mülldaten: int main(void) { boot(); int buffer[12]; // Eine Testmsg in den TX Buffer schreiben. sja1k(0x10,write,0x88); // EFF Frame Information sja1k(0x11,write,0x00); // Identifier sja1k(0x12,write,0x00); sja1k(0x13,write,0x00); sja1k(0x14,write,0x08); sja1k(0x15,write,0xFF); // 8 Data Bytes sja1k(0x16,write,0xCD); sja1k(0x17,write,0xEF); sja1k(0x18,write,0xF0); sja1k(0x19,write,0x12); sja1k(0x1A,write,0x34); sja1k(0x1B,write,0x45); sja1k(0x1C,write,0x67); sja1k(0x01,write,0x10); // msg abschicken mit Self reception if (sja1k(0x02,read,0)&0x01) { // im Statusregister schauen ob Receive Buffer voll, also ob eine Msg empfangen wurde // Msg in einem Buffer speichern buffer[0] = sja1k(0x10,read,0); buffer[1] = sja1k(0x11,read,0); buffer[2] = sja1k(0x12,read,0); buffer[3] = sja1k(0x13,read,0); buffer[4] = sja1k(0x14,read,0); buffer[5] = sja1k(0x15,read,0); buffer[6] = sja1k(0x16,read,0); buffer[7] = sja1k(0x17,read,0); buffer[8] = sja1k(0x18,read,0); buffer[9] = sja1k(0x19,read,0); buffer[10] = sja1k(0x1A,read,0); buffer[11] = sja1k(0x1B,read,0); buffer[12] = sja1k(0x1C,read,0); sja1k(0x01,write,0x04); // release receive buffer // msg auf dem Display anzeigen lcd_command(0x80); lcd_hex_digit(buffer[0]); lcd_hex_digit(buffer[1]); lcd_hex_digit(buffer[2]); lcd_hex_digit(buffer[3]); lcd_command(0xc0); lcd_hex_digit(0xAA); lcd_hex_digit(buffer[5]); lcd_hex_digit(buffer[6]); lcd_hex_digit(buffer[7]); lcd_command(0x90); lcd_hex_digit(buffer[8]); lcd_hex_digit(buffer[9]); lcd_hex_digit(buffer[10]); lcd_hex_digit(buffer[11]); // lcd_hex_digit(buffer[12]); // Passt nimmer } } Folgender Code funktioniert und liefert die gesendete Msg auf das Display: int main(void) { boot(); // int buffer[12]; // Eine Testmsg in den TX Buffer schreiben. sja1k(0x10,write,0x88); // EFF Frame Information sja1k(0x11,write,0x00); // Identifier sja1k(0x12,write,0x00); sja1k(0x13,write,0x00); sja1k(0x14,write,0x08); sja1k(0x15,write,0xFF); // 8 Data Bytes sja1k(0x16,write,0xCD); sja1k(0x17,write,0xEF); sja1k(0x18,write,0xF0); sja1k(0x19,write,0x12); sja1k(0x1A,write,0x34); sja1k(0x1B,write,0x45); sja1k(0x1C,write,0x67); sja1k(0x01,write,0x10); // msg abschicken mit Self reception if (sja1k(0x02,read,0)&0x01) { // im Statusregister schauen ob Receive Buffer voll, also ob eine Msg empfangen wurde lcd_command(0x80); lcd_hex_digit(sja1k(0x10,read,0)); lcd_hex_digit(sja1k(0x11,read,0)); lcd_hex_digit(sja1k(0x12,read,0)); lcd_hex_digit(sja1k(0x13,read,0)); lcd_command(0xc0); lcd_hex_digit(sja1k(0x14,read,0)); lcd_hex_digit(sja1k(0x15,read,0)); lcd_hex_digit(sja1k(0x16,read,0)); lcd_hex_digit(sja1k(0x17,read,0)); lcd_command(0x90); lcd_hex_digit(sja1k(0x18,read,0)); lcd_hex_digit(sja1k(0x19,read,0)); lcd_hex_digit(sja1k(0x1A,read,0)); lcd_hex_digit(sja1k(0x1B,read,0)); // lcd_hex_digit(buffer[12]); // Passt nimmer sja1k(0x01,write,0x04); // release receive buffer } } Ich hatte mir da schon schöne Funktionen geschrieben, die ein Struct "CAN_MSG" benutzen usw. Aber die haben auch alle nicht funktioniert, da es anscheinend schon daran scheitert, die Daten simpel in Variablen zu speichern. Werden die Daten direkt in die Anzeigefunktion übergeben funktioniert es also. Aber warum? Speicher sollte genug da sein. Immerhin teste ich mit einem Mega32 mit 2kb SRAM (aber es läuft ja auch auf einem AT90S4433 genauso gut bzw schlecht). Gibts in C irgendwas zu beachten, was ich vielleicht nicht weiss? Hatte nie derartige Probleme ein Array zu befüllen (unter Visual C++ hats zumindest so immer funktioniert). GCC Einstellugen vielleicht? Hat es vielleicht mit dem Rückgabewert der Funktion "sja1k" zu tun (der ist vom Typ int)?
Ein Array aus 12 Elementen mit 13 Daten zu füllen muß ja in die Hose gehen. Peter
Du weisst aber, daß man bei "0" beginnt zu zählen? Also ein int array[12] initialisiert ein Array mit 13 Elementen, da die 0 das erste Element ist.
Nein, ein array[12] ergibt ein Array mit 12 Werten. Und zwar 0 - 11 .
Stimmt. Hab grad nachgeschaut. Entschuldigung Peter. Trotzdem ist irgendwo der Wurm drin, denn auch wenn ich mein Array mit int buffer[13] initialisiere funktioniert es nicht besser. nehme ich 13 einzelne Int Variablen, dann geht es übrigens jetzt. Es darf halt blos kein Array sein... Was mach ich blos falsch.
Hi LtData Hatte schon mal gepostet, aber niemand wollte mir helfen. Vielleicht hattest Du ja das gleiche Problem. Ich hab nen 82c200 (Vorgänger des sja1000) an einem 8515 hängen. Mein Problem ist, daß der ab und zu mal die gesendeten Daten nicht empfängt. Ist allerdings nicht regelmäßig. Ein gleichzeitig am Bus hängender 81c90 hat mit den gleichen Daten keine Probleme. Da Timing ist bei beiden identisch eingestellt. Hast Du eine Idee ? Gruß Boris
Wenn das Array die richtige Größe hat, vielleicht liegts am Typ. Ich weiß ja nicht, wie sja1k() und lcd_hex_digit() definiert sind, d.h. wie und ob eine Typkonvertierung erfolgt. Versuch doch mal: unsigned char buffer[13]; Peter
@Boris ne da kann ich Dir nicht helfen. Ich bin froh, daß sich zumindest jetzt die Controller gegenseitig Messages anscheinend korrekt zuschicken können. Derartige Probleme wie Du hatte ich bis jetzt noch nicht. Also bisher ist noch jede Nachricht irgendwie angekommen. Blos ganz zu Anfang, als noch überhaupt nix funktioniert hat, da hats bei mir am Timing gelegen. Vielleicht solltest Du mal ein langsameres Timing hernehmen. Oder mal schauen ob der Controller wenigstens etwas erkennt, d.h. etwas in seine Fehlerstatusregister geschrieben hat. @Peter die Definitionen lauten wie folgt: int sja1k(int addresse, enum DIRECTION direction, int data) void lcd_hex_digit(int digit) Da sollte also eigentlich keine Typumwandlung stattfinden. Ich habe eigentlich immer für alle Variablen "int" genommen, da es sich ja immer um ein Byte handelt. Aber da gibts noch was komisches: Ich hatte mir für eine Can Msg folgendes Struct geschrieben: struct CAN_MSG { uint8_t ident; uint8_t id0; uint8_t id1; uint8_t id2; uint8_t id3; uint8_t data0; uint8_t data1; uint8_t data2; uint8_t data3; uint8_t data4; uint8_t data5; uint8_t data6; uint8_t data7; }; Zugegeben, daß ich da uint8_t genommen habe, aber das erklärt IMHO nicht die Reaktion auf mein Struct. Das Programm lässt sich kompilieren und läuft auch zunächst. eine Zeile wie struct CAN_MSG can_msg; wird noch ausgeführt. Bei einer Zeile wie can_msg.ident = 0x88; stürzt mein Programm auf dem Atmel aber ab und beginnt wieder ganz von vorne. Es bleibt nicht hängen. Ich konnte mir das nie erklären und hab daher einfach kein struct mehr benutzt. Ich werde jetzt erstmal mit anderen Datentypen experimentieren. Wenn ihr wollt, kann ich auch mal den kompletten Source posten. Der ist aber leider nicht mehr so schön durch das ständige verzweifelte ausprobieren. Ich denke auch mal, wenn es am GCC (GNU GCC 3.3 20030421 (prerelease) - das ist der, den man bei avrfreaks bekommt) liegen würde, dann wäre das sicher schon anderen aufgefallen. Oder es ist irgendeine GCC Einstellungssache, von der ich nix weiss...
Generell sollte man immer den passenden Typ nehmen. D.h. "int" auch nur dann, wenn wirklich 16 Bit benötigt werden und "unsigned" immer, wenn negative Werte keinen Sinn ergeben. Z.B. bei Daten und Adressen sollte alles positiv, also "unsigned" sein. "int" ohne "unsigned" davor macht eigentlich nur bei echten Meßwerten Sinn (negative Temperatur, Spannung usw.). Bei logischen Daten und Operationen damit kann Dir das Vorzeichen aber die komischsten Effekte verursachen. Auch wenn Du genügend Speicher hast, bringt es absolut nichts ein Byte als "int" zu speichern und damit Ressourcen zu verschwenden. Jede 8-Bit CPU muß "int" erst umständlich durch Kaskadierung von mehreren 8-Bit Operationen simulieren. Es gibt da auf der Atmel AVR-Seite eine schöne Application Note, wie man effektiv und übersichtlich unter C programmiert. Peter
mittlerweile hab ich alles auf uint8_t umgeschrieben und es funktioniert hm... besser. Aber immer noch nicht gut. Mein struct funktioniert jetzt auch halbwegs. Zumindest stürzt der Atmel nicht mehr ab, aber es sind immer noch teilweise falsche Daten vorhanden, wie beim Array. Mit ganz normalen Variablen funktioniert es dagegen gut. Aber man muss doch auch mit nem Struct und/oder Array hantieren können... Mein Struct und mein Array bestehen übrigens logischerweise bisher immer aus 13 Bytes. Interessant ist, daß offensichtlich die erstsen 4 Bytes korrekt sind, dann kommen 2 falsche, dann 1 richtiges, 2 falsche, 2 richtige, 1 falsches und das letzte kann ich nicht beurteilen, da es nicht mehr auf meinem Display angezeigt wird. Ich kann mir das nicht erklären. Den falschen Bytes kommt im Programm keine Sonderbehandlung zugute.
Wie meinst Du das? Willst Du den Inhalt der Konfigregister haben? Dazu bräuchtest Du auch das Datenblatt. Initialisiert wird er übrigens über die selbe Funktion ("sja1k"), die oben verwendet werden. Na egal ich poste einfach mal meine Initialisierungsbefehle: sja1k(0x00,write,0x01); // RESET MODE aktivieren sja1k(0x1f,write,0xC9); // Peli CAN MODE und andere Einstellungen vornehmen sja1k(0x06,write,0xC7); // Register BTR0 schreiben sja1k(0x07,write,0xD7); // Register BTR1 schreiben sja1k(0x08,write,0xDA); // push & pull output sja1k(0x04,write,0x00); // Interrupts erstmal ausschalten sja1k(0x00,write,0x00); // zurueck in den Normal Mode: ferig! Wie gesagt es kann ja eigentlich nicht am SJA liegen, denn mit 13 einzelnen Variablen gehts ja und mit einem Array mit 13 Elementen gehts nicht. Ob ich wohl einfach mal nen anderen GCC runterladen sollte?
Hallo ! Ich will mit dem AVR 8535 CAN Botschaften senden und empfangen. Dazu verwende ich einen SJA1000. Kann mir jemand dazu Infos geben? (Hardwareaufbau und Software) Ich habe keinen Plan!!!
@Leonhardt: Es ist auf jeden Fall ganz wichtig, das Du möglichst viele Threads aufmachst und in ganz vielen Beiträgen mehrfach deine Hilferufe postest. Dann wird dir bestimmt geholfen. Andere hätten vielleicht nur gesagt: Wer suchet der findet..
Vielleicht liegts am BitTiming?! (siehe http://www.elektroniknet.de/topics/automatisieren/fachthemen/artikel/1997/ek9722b_1.htm) Gruss Michael
Hallo! @LtData Bin auch dabei einen SJA1000 mit einem AVR anzusteuern! Könntest Du mir Deinen Source zukommen lassen? Wäre prima! Falls natürlich sonst noch jemand mir helfen kann (und will), bin ich um jede Hilfe verlegen.. Gruß, Sascha
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.