mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik R8C29 LIN Kommunikation


Autor: Manuel (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Rudi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Judge (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Judge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Manuel,

die Initialisierung des Quarzes könnte folgendermassen aussehen:
  prc0 = 1;           // Disable register protect
  cm13 = 1;           // Enable Xin-Xout
  cm05 = 0;           // Start main clock
  asm("nop");         // Stabilize crystal
  asm("nop");         // (adapt delay to oscillator)
  asm("nop");
  asm("nop");
  cm06 = 0;           // No division
  ocd2 = 0;           // Set main clock as system clock
  cm14 = 1;           // Disable on-chip oscillator
  cm15 = 0;           // Drive capacity: low
  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:
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

Autor: Judge (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.