Forum: Mikrocontroller und Digitale Elektronik PIC18F: Probleme mit CAN


von Candongle (Gast)


Angehängte Dateien:

Lesenswert?

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

von Anja (Gast)


Lesenswert?

Candongle schrieb:
> Oder mache ich sonst einen
> Anfängerfehler?

Wo ist der Abschlußwiderstand für den CAN-Bus?

Gruß Anja

von Anja (Gast)


Lesenswert?

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

von Candongle (Gast)


Lesenswert?

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

von Candongle (Gast)


Lesenswert?

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

von Candongle (Gast)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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

von Candongle (Gast)


Lesenswert?

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

von Anja (Gast)


Lesenswert?

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.

von Candongle (Gast)


Lesenswert?

Danke für die Erklärung! So erklärt ists doch schon klar ;o))

Grüessli

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
Noch kein Account? Hier anmelden.