Forum: Mikrocontroller und Digitale Elektronik ubrr Register beschreiben mit UL(=32 bit?), nur 12 bit von ubrr verwenden?


von Nikolaus (Gast)


Lesenswert?

Schöne Grüße an das Forum,

zwei Anfänger-Verständnisfragen zum Beschreiben des ubrr Register der 
ATMEGA Controller.

Ein üblicher Code lautet auszugsweise (z.B. aus dem UART manual von 
mikrocontroller.net) :

#define BAUD 9600UL      // Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
....
UBRR0 = UBRR_VAL;

oder

UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;

je nach verwendetem Atmega Typ.

1.Frage
Soweit ich verstanden habe, dienen die obigen Schreibbefehle zum 
beschreiben von zwei 8 Bit Registern mit einer 16 bit Zahl.
Nun ist die im Präprozessor definierte U(nsigned)L(ong) Zahl laut AVR 
GCC manual doch eine 32 bit Zahl (oder machen die 8 bit ATMEGA trotzdem 
eine 16 bit Zahl daraus?).
Nachdem obiger Code sicher stimmt und tausendfach verwendet wird sehe 
ich hier offensichtlich etwas falsch. Was ist falsch an meiner 
Überlegung?

2.Frage

Laut Mikroprozessor manual werden von UBRRH ja nur 4 Bits für die 
Baudrate verwendet.
Die anderen 4 Bits sind zum Teil belegt (zB mit URSEl oder leer).

Z.b Auszug aus dem ATMEGA 1284P manual (dort gibts kein URSEl )steht 
aber so ähnlich bei allen drin.

"
• Bit 15:12 – Reserved
These bits are reserved for future use. For compatibility with future 
devices, these bit must be written to zero when UBRRH is written.

• Bit 11:0 – UBRR11:0: USART Baud Rate Register
This is a 12-bit register which contains the USART baud rate. The UBRRH 
contains the four most significant bits, ..."

Also schreibt man salopp gesagt mit obigen Befehl eine 16 Bit Zahl auf 
zwei 8 bit Register die eigentlich nur eine 12 bit Zahl enthalten 
sollen. Geht das? Warum geht das? Wie wird sichergestellt das die 
"obersten" vier Bit wirklich 0 bleiben?

Vielen Dank für Antworten im voraus.

Nikolaus

von Nikolaus (Gast)


Lesenswert?

Könnte der Grund sein, dass UBRR sowieso nicht größer als 2^12=4096 
werden kann und damit die 20 anderen Bits sowieso immer 0 sind und es 
damit egal ist wie lange UBBR_VAL in obigem Beispiel ist (16 Bit, 32 
Bit, 64 Bit ...)?

Nikolaus

von H.Joachim S. (crazyhorse)


Lesenswert?

(F_CPU+BAUD*8)
Das ist der Grund, das Zwischenergebniss passt nun mal nicht in eine 
16bit-Zahl. Nach der anschliessenden Division ist alles in bester 
Ordnung.

von Nikolaus (Gast)


Lesenswert?

Ist es beim Schreiben auf Register möglich, dass bei Verwendung einer zu 
langen Zahl (zB 16 bit Zahl bei 8 bit Register) ungewollt auf ein 
Nachbarregister geschrieben wird. Oder geht das aufgrund der 
Organisation/des Aufbaus des Mikrocontrollers gar nicht?

In obigem Besipiel würde dies ja bedeuten das die sechzehn übeschüssigen 
0 auf den Adressbereich davor geschrieben werden?

Nikolaus

von Jim M. (turboj)


Lesenswert?

Nikolaus schrieb:
> Ist es beim Schreiben auf Register möglich, dass bei Verwendung einer zu
> langen Zahl (zB 16 bit Zahl bei 8 bit Register) ungewollt auf ein
> Nachbarregister geschrieben wird. Oder geht das aufgrund der
> Organisation/des Aufbaus des Mikrocontrollers gar nicht?

Geht nicht. Dafür ist allerdings der C Compiler zuständig der die 
entsprechende Anweisung generiert. Die obigen UBRRH und UBRRL sind als 1 
Byte deklariert, also generiert er Instruktionen die 1 Byte schreiben. 
Siehe entsprechende Header Datei.

Das ist dasselbe wie bei
1
uint8_t b = 320;

da schreib er auch nur das eine Byte, also modulo 256.

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.