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