www.mikrocontroller.net

Forum: Mikrocontroller und Elektronik R8C29 LIN Kommunikation

Autor: Manuel (Gast)
Datum: 23.01.2008 13:03
Dateianhang: main_lin_slave.c (8,1 KB, 94 Downloads) | formatierter Code

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: 23.01.2008 13:46

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: 11.02.2008 14:48

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: 11.02.2008 22:52

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: 13.02.2008 17:05

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: 13.02.2008 21:42

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: 13.02.2008 22:03

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 Email-Adresse ist freiwillig. Wenn Sie automatisch per Email über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Suchfunktion und Betreffsuche benutzen - vielleicht gibt es schon einen ähnlichen Beitrag
  • Aussagekräftigen Betreff wählen
  • Im Betreff angeben um welchen Controllertyp es geht (AVR, PIC, ...)
  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
  • JPEG-Dateien (.jpg) nur für Fotos und Scans verwenden
  • Schaltpläne, Screenshots usw. als PNG oder GIF anhängen

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [pre]vorformatierter Text (z.B. Code in anderen Sprachen)[/pre]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel






webmaster@mikrocontroller.netImpressumWerbung auf Mikrocontroller.net