Salu zusammen Ich habe ein kleines Problem mit meinem PIC18F46K80 und dem internen CAN-Bus. Der Treiber basiert auf dem von Microchip Maestro. Musste diverse Register ect. anpassen bis es sich kompilieren liess, aber das funktioniert nun. Ich muss dazu sagen, dass dies mein erster Versuch mit CAN ist, also bitte nicht schlagen wenn ich einen riesen Anfängerfehler begehe ;o) Was funktioniert: Ich habe meine HW mit einem CAN Dongle von IXXAT verbunden. Im Terminalprogramm kann ich sehen, dass Daten von meiner HW am PC ankommen. Leider nicht alle. Ich habe auf meiner HW einen Timer Interrupt welcher mir alle 500ms eine Variable setzt. Ist diese Variable gesetzt wird eine andere Variable einfach um 1 inkrementiert und der neue Wert via CAN-Bus an den PC geschickt. Ich kann ja bis zu 8 Datenbytes schicken (von HW an PC). Sende ich nun nur 1 Datenbyte klappt alles recht gut. Die Werte kommen ca. alle 500ms am PC an. Bei 2 Datenbytes habe ich immer wieder mal „Löcher“ in den Daten. Sprich z.b. 0x01,0x02,0x04. Wenn ich 3 oder mehr Datenbytes schicke kommt nichts mehr an, oder dann nur alle paar Sekunden. In diesem Zustand kommt dann auch rel. schnell ein Bus Error (sehe ich im Terminalprogramm (MiniMon), aber leider ist er nicht genauer beschrieben um was für einen Error es sich handelt, jedoch erhöht sich der TXErrorCounter) Ich kann jedoch sagen, dass die HW nicht Bus Off geht, sprich, der Bus läuft immer noch weiter (mit Oszi gemessen) Er hängt sich also nicht komplett auf. Auch habe ich keinen Overflow ect. da leuchten alle LED grün. Wenn ich Daten vom PC an die HW schicke kommen diese ebenfalls an (Interrupt auf HW wird angesprungen und Daten gelesen) Hier habe ich aber dasselbe Phänomen, die ersten Bytes sind korrekt und danach wird’s immer wilder Untersucht und i.O - Die Signale (CAN_H/CAN_L) habe ich mit dem Oszi untersucht, sehen sauber aus - Die Baudrate habe ich auf 125kB gesetzt. Das Terminalprogramm stellt auch 125kB ein wenn ich Auto Baudrate drücke und das ist auch die einzige Einstellung in der Daten ankommen, respektive gesendet werden können. Hier meine Senderoutine, can_send wird alle 500ms auf 1 gesetzt: if(can_send == 1) { TX_Message.Address = MY_ADDRESS_IDENTIFIER;//Set the address to My identifier #ifdef MY_ADDRESS_IS_STANDARD TX_Message.Ext=0;//If the identifier is standard, clear the Ext flag else TX_Message.Ext=1;//If the identifier is extended, set the Ext flag #endif TX_Message.NoOfBytes = 1; TX_Message.Data[0] = TX_Message.Data[0] + 1; TX_Message.Data[1] = 0x02; TX_Message.Data[2] = 0x03; TX_Message.Data[3] = 0x04; TX_Message.Data[4] = 0x05; TX_Message.Data[5] = 0x06; TX_Message.Data[6] = 0x07; TX_Message.Data[7] = 0x08; TX_Message.Remote = 0; //clear the remote flag TX_Message.Priority = 3;//Internal CAN module priority 0-> least priority, 3-> most priority CANPut(TX_Message); //Put the message in the FIFO can_send = 0; } Die eigentliche CANPut könnt ihr der angehängten can.c entnehmen, die ist dort enthalten. Das ist eben diese Datei welche von Maestro erzeugt wurde. Header kann ich noch nachreichen falls die jemand auch anschauen möchte. Ich denke es könnte etwas mit der Baudrate sprich den Phase Segments nicht stimmen. Hier noch meine Einstellungen #define BAUD_RATE_PRESC 21 #define SJW_TIME 1 #define SAMPLES 1 #define PROP_TIME 1 #define PH_SEG_1 8 #define PH_SEG_2 2 Ich habe am PIC einen Quarz mit 16MHz und die interne PLL ist aktiviert, also 64MHz Clock. Hat vielleicht jemand von Euch Erfahrung mit den obengenannten Phänomenen, oder hat jemand bereits diesen Treiber von Microchip erfolgreich zum laufen gebracht? Oder mache ich sonst einen Anfängerfehler? Wäre über jede Hilfe dankbar! Grüessli Candongle
Candongle schrieb: > Oder mache ich sonst einen > Anfängerfehler? Wo ist der Abschlußwiderstand für den CAN-Bus? Gruß Anja
Candongle schrieb: > #define BAUD_RATE_PRESC 21 > #define SJW_TIME 1 > #define SAMPLES 1 > #define PROP_TIME 1 > #define PH_SEG_1 8 > #define PH_SEG_2 2 Das sieht auf den ersten Blick wenig vertrauenerweckend aus: Bei einem vielfachen von 16 MHz würde man für alle Segmente die Summe der Dauern auf ein vielfaches von 8 (meist 16) setzen. Der Sample-Point dann irgendwo zwischen 75% und 85%. (Abhängig von Bus-Länge). Vorsicht: meistens wird "Segmentlänge - 1" als Registerwert programmiert. 125kBaud sind dann im Prescaler auch ein Teilverhältnis als vielfaches von 8. Gruß Anja
Salu Anja Ich habe bereits mit Abschlusswiderständen probiert: 120Ohm, 60Ohm auf einer Seite ect. hat alles nix gebracht. Wie gesagt, die Signale sehen mit dem Oszi gemessen sauber aus (Flanken, Pegel) Hmmm, bei Deiner Betrachtung der Segmente steige ich jetzt noch nicht ganz durch. Könntest Du mir das vielleicht genauer erläutern. Ich habe zu diesen Phase Segments ect. viel gefunden und gelesen, aber je mehr ich gelesen habe desto mehr hats mich verwirrt. Anscheinend haben das nicht gerade viele Leute wirklich verstandne und übernehmen einfach irgendwelche Einstellungen von anderen Projekten oder aus dem Netz. Aber wie man genau draufkommt bleibt meist verborgen Grüessli und danke für die Hilfe Candongle
PS: Habe das vielleicht nicht klar ausgedrückt. Im Moment habe ich eine Buslänge von ca. 1m und diesen habe ich mit 120Ohm abgeschlossen (sicher nicht optimal, aber ich dachte bei 1m Kabel und 125kB müsste das reichen. Ist das ein Trugschluss? Grüessli
Salu zusammen Ich habe ein bisschen im Netz geforscht und bin da auf ein Tool gestossen um diese Time Quanta zu berechnen (MBTime.exe). Scheint von ziemlich vielen eingesetzt zu werden. Ausprobieren kann ich es leider erst später. Aber hier mal die Werte die mir dieses Tool ausgespuckt hat: Input: 64MHz Clock / 125kB CAN Speed Output: #define BAUD_RATE_PRESC 15 #define SJW_TIME 1 #define SAMPLES 1 #define PROP_TIME 1 #define PH_SEG_1 8 #define PH_SEG_2 6 Kann man da schon eine Aussage treffen ob das jetzt besser ist, als das was ich zuvor eingestellt hatte? Denke ja schon ;o)) Irgendwie denke ich, dass das alles ja nicht so kompliziert sein kann. Ich glaube ich stehe mir mal wieder selber am meisten im Weg g Grüessli
Candongle schrieb: > #define BAUD_RATE_PRESC 15 > #define SJW_TIME 1 > #define SAMPLES 1 > #define PROP_TIME 1 > #define PH_SEG_1 8 > #define PH_SEG_2 6 http://ww1.microchip.com/downloads/en/DeviceDoc/39977f.pdf Siehe Seite 446 So wird das nix: den sample point sollst Du auf >= 75% legen Also z.B. TQ = 500ns -> prescaler = 64MHz 2MHz 2 = 16 -> 15 ins Register bleiben 16 TQ für 125kBaud 4 TQ PH_SEG_2 -> Register = 3 für 75% 8 TQ PH_SEG_1 -> Register = 7 3 TQ PROP_TIME -> Register = 2 1 TQ Sync SJW kann 1 oder 2 sein (Register = 0 oder 1) Irgendwo in deinem Code sollten die Werte dann auch ins entsprechende Register geschrieben werden (z.B. CanOpen-Aufruf). Ein #define alleine hilft leider nix. Gruß Anja
Salu Anja Also mit den oben angegebenen Werten (die die ich gepostet habe) > #define BAUD_RATE_PRESC 15 > #define SJW_TIME 1 > #define SAMPLES 1 > #define PROP_TIME 1 > #define PH_SEG_1 8 > #define PH_SEG_2 6 funktioniert es 1A. Hatte keinen einzigen Error mehr. Die Daten rauschen über die Leitung wie sie sollten. Werde Deine Werte aber sehr gerne mal probieren. Musste jedoch BAUD_RATE_PRESC auf 16 setzen, mit 15 wars nix. Da wird in der Zuweisungsfunktion 1 subtrahiert... Die Werte werden natürlich noch in die Register geschrieben ;o) Ich habe, wie Eingangs beschrieben, einfach mal die Source von Maestro als Basis genommen. Jetzt bin ich daran den Code komplett neu zu machen, nach meinem Gusto ;o) So hats dann nur noch das drin was es wirklich braucht und ich habe auch schon wieder viel gelernt. Habe mich schon mit so eingien Bussen beschäftigt, aber so Mühe wie beim CAN-Bus hatte ich schon lange nicht mehr. Keine Ahnung warum. Wenn mans aber mal verstanden hat kann man sich gar nicht mehr erklären wieso man so lang gebraucht hat ;o) Vielen Dank nochmals für die Hilfe. Ich habe das mit den >=75% auch mehrfach gelesen, aber komischerweise halten sich sehr viele nicht daran... Frag mich nur gerade warum? Ich werde aber Deine Einstellungen sicher noch testen und berichten Merci nochmals für die Hilfe! Grüessli Candongle
Candongle schrieb: > Ich habe das mit den >=75% auch > mehrfach gelesen, aber komischerweise halten sich sehr viele nicht > daran... Frag mich nur gerade warum? Die Ursache ist daß je später der Sample-Point umso länger ist die mögliche Einschwingzeit also desto länger die maximale Leitungslänge. Die Übertragung wird also zuverlässiger je später der Samplepoint. Allerdings darf dann SJW_TIME nicht mehr so groß gewählt werden. D.h. mit späterem Samplepoint muß der CAN-takt auch genauer sein. Open-Can verwendet sogar 87% Sample-Point als Standardwert.
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.