Forum: Mikrocontroller und Digitale Elektronik R8C29 LIN Kommunikation


von Manuel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen
Ich möchte ein Evaluation Board mit einem R8C29 als LIN Slave 
programmieren.
Mit einem Laptop als Master sende ich ständig einen Header an das Board. 
Der auch bis zum Port 1_5 anliegt.
Ich verwende zur Initialisierung der LIN-Kommunikation ein BspFile von 
Renesas. Der funktioniert auch soweit doch bleibt er hängen bei der 
Abfrage ob das Synch Field measurement completed flag gesetzt ist.

Ich sende mal mein File mit vielleicht kann ja mal bitte jemand drüber 
schauen. Vielen Dank

von Rudi (Gast)


Lesenswert?

Hallo Manuel,

ich habe zwar noch nie mit LIN gearbeitet - aber ist es so gewollt, dass 
du in deiner Endlosschleife "while(1)" ständig den Hardwareteil 
initialisierst? Ich denke, dass hier ein einmaliger Durchlauf genügt und 
du danach entsprechende Flags abfragen kannst - oder irre ich mich da?

Beste Grüße

Rudi

von Manuel (Gast)


Lesenswert?

Hallo Rudi,

vollkommen richtig die Schleifen warten darauf das die Hardware gesetzt 
wird. Ich bin der Meinung das ich meine Hardware richtig gesetzt habe 
und mein Master ein ordentliches LIN Signal ausgibt. Das kommt auch am 
entscheidenen RXD PIN an. Aber leider funzt nix

von Judge (Gast)


Lesenswert?

Hallo Manuel,

die Schleifen sind soweit korrekt. Allerdings müssen die Bits b0clr, 
b1clr und b2clr zum Löschen der Status-Flags auf "1" gesetzt werden, 
nicht auf "0".

Was ich bei Dir im Programm allerdings vermisse ist die Initialisierung 
eines Quarzes oder des High-Speed On-Chip Oszillators für die 
LIN-Kommunikation. D.h. Dein Programm läuft vermutlich mit dem Low-Speed 
On-Chip Oszillator (~125 kHz) und daher passt das Timing nicht.

Gruß
Judge

von Manuel (Gast)


Lesenswert?

Hallo Judge

mit den Flags das hab ich schon geändert. Aber mit dem Timing hab ich 
wirklich nen Problem. Leider weiß ich nicht wie ich den Quarz 
initialisieren soll. Ich dachte der nimmt den Quarz vom Board (20 MHz). 
Ein anderes Problem ist er nimmt mein gesendeten Header nicht an. Als 
erstes in einer Nachricht gibt es doch den Sync Break der >=13Bit ist. 
Der muss mit dem Timer ausgemessen werden. Dazu verwendet man einen 
Timer und einen Prescaler. Weiß jemand wie man das macht mit Baudrate 
Quarztakt und ...

Vielen Dank

von Judge (Gast)


Lesenswert?

Hallo Manuel,

die Initialisierung des Quarzes könnte folgendermassen aussehen:
1
  prc0 = 1;           // Disable register protect
2
  cm13 = 1;           // Enable Xin-Xout
3
  cm05 = 0;           // Start main clock
4
  asm("nop");         // Stabilize crystal
5
  asm("nop");         // (adapt delay to oscillator)
6
  asm("nop");
7
  asm("nop");
8
  cm06 = 0;           // No division
9
  ocd2 = 0;           // Set main clock as system clock
10
  cm14 = 1;           // Disable on-chip oscillator
11
  cm15 = 0;           // Drive capacity: low
12
  prc0 = 0;           // Enable register protect
Nach dem Reset läuft erstmal nur der On-Chip Oscillator. Eine 
Umschaltung ist also erforderlich.

Das Timing liegt aber ohnehin voll daneben. Ich nehme mal an Du möchtest 
die LIN-Schnittstelle bei 19200 bps betreiben?

Demnach müsste für die UART folgende Einstellung vorgenommen werden:
u0brg = [(20 MHz)/(16*19200)] - 1 = 64

Die Bitzeit ergibt sich damit zu: 1/19200 => ~52.08 µs

Timer RA muss nun so eingestellt werden, dass er z.B. mehr als 11 
Bit-Zeiten (also ~573 µs) als Synch-Break erkennt. Der Prescaler und der 
Timer werden in Deinem Programm mit 177 bzw. 63 geladen. D.h., dass mehr 
als
[(177 + 1)*(63 + 1)]/(20 MHz) = 569.6 µs
als Synch-Break erkannt werden. Passt also.

Wird der Synch-Break erkannt, misst der Timer anschliessend das 
Synch-Field (8 Bit-Zeiten). Im Idealfall wären das:
(8 * 20 MHz)/19200 = ~8333 Timer-Ticks (=> trapre = 32; => tra = 141)

Setze ich das jetzt in Deine Berechnungsformel für die Synchronisation 
ein, kommt da allerdings ein negativer Wert heraus?! Die Formel scheint 
also einen Fehler zu haben.
Statt über die Look-up Table könnte man den Wert für das 
Baudrate-Register auch direkt berechnen:
1
u0brg = (u08)((((u16)trapre << 8)|tra)/128) - 1;
Die Teilung durch 128 kommt durch die 8 Datenbits und die Teilung durch 
16 der UART zustande.

Der Rest wäre dann einfach nur noch UART-Kommunikation.

Gruß
Judge

von Judge (Gast)


Lesenswert?

Hoppla, vergiss den letzten Teil mit der Berechnung. Ich habe ja ganz 
übersehen das der Timer noch mit den Werten vom Synch-Break vorgeladen 
ist und dann rückwärts zählt.
D.h. die Berechnung mit der Look-up Table könnte evtl. doch passen. 
Probier es am Besten einfach noch mal aus.

Gruß
Judge

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.