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
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
(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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.