Forum: Mikrocontroller und Digitale Elektronik AVR: UBRR Berechnung (2 verschiedene Formeln)


von mik (Gast)


Lesenswert?

Hi Leute, habe in der UART-Forum-Beschreibung eine Formel gefunden die 
mit der des Atmega16 übereinstimmt, aber im Beispielassembler code steht 
dann eine andere. Könnte mir das wer erklären? Lieegt das am Assembler, 
dass diese Formel im Code verwendet wird? Ich will nämlich auch eine 
Interrupt-Empfangsroutine schreiben, nur mach ich das mit Micropascal 
und bei der UBRR berechnung blick ich nicht ganz durch.


1) Atmega16 Datasheet und Forum-Uartbeschreibung:
UBRR = f / (16*BAUD) -1

2) Forum-Uartbeschreibung Assemblercode:
UBRR = ( f+BAUD*8 ) / (BAUD*16) -1


BEISPIEL:
f=8 000 000
BAUD= 14400

1) UBRR= 33.7222....
2) UBRR= 34.22222....

Was für einen Wert verwendet man nun? Rundet man auf oder ab?
Danke für jeden Tipp,
MM

von Eddy C. (chrisi)


Lesenswert?

Man rundet so, wie Du es in der Schule gelernt hast. Da aber 
Kommastellen in der Berechnung nicht berücksicht werden können 
(Integerarithmetik), benutzt man den Trick und addiert die Hälfte des 
Divisors zum Dividenden. Daraus ergibt sich dann korrektes Runden trotz 
Integer. Die 2. Formel ist also die "Genauere". Wunder kann sie 
allerdings auch nicht vollbringen.

von Falk B. (falk)


Lesenswert?

@ mik (Gast)

>Hi Leute, habe in der UART-Forum-Beschreibung eine Formel gefunden die
>mit der des Atmega16 übereinstimmt, aber im Beispielassembler code steht
>dann eine andere. Könnte mir das wer erklären? Lieegt das am Assembler,

>1) Atmega16 Datasheet und Forum-Uartbeschreibung:
>UBRR = f / (16*BAUD) -1

Das ist die offizielle Formel. Wenn man die manuell in den 
Taschenrechner hackt und keinen Baudratenquarz verwendet, kommt eine 
Zahl mit Nachkommastellen raus. Die sollte man sinnvollerweise runden, 
damit der Fehler minimiert wird. Also 22,8 wird man auf 23 aufrunden, 
22,1 auf 22. Wenn man die Formel aber so in das Makro schreibt, dann 
wird NICHT gerundet, sondern die Nachkommastellen abgeschnitten 
(truncation). Somit wird aus 22,8 genauso wie aus 22,1 eine 22. Unschön.

>2) Forum-Uartbeschreibung Assemblercode:
>UBRR = ( f+BAUD*8 ) / (BAUD*16) -1

Das ist ein Trick, duch den man runden kann.

>1) UBRR= 33.7222....

Genau, per "Hand" wird auf 34 gerundet. Der Compiler würde auf 33 
abschneiden.

>2) UBRR= 34.22222....

Hier schneidet der Compiler korrekt auf 34 die Nachkommastellen ab.

Steht ja auch so als Kommentar dort ;-)

>Was für einen Wert verwendet man nun? Rundet man auf oder ab?

Man rundet mathematisch korrekt.

MFG
Falk

von Karl H. (kbuchegg)


Lesenswert?

mik wrote:
> 1) Atmega16 Datasheet und Forum-Uartbeschreibung:
> UBRR = f / (16*BAUD) -1

Das ist die plain vanilla Berechnung

>
> 2) Forum-Uartbeschreibung Assemblercode:
> UBRR = ( f+BAUD*8 ) / (BAUD*16) -1

Das zusätzliche Glied sorgt dafür, dass gerundet wird

>
> BEISPIEL:
> f=8 000 000
> BAUD= 14400
>
> 1) UBRR= 33.7222....
> 2) UBRR= 34.22222....

Bei der Berechnung kommt weder 33.7222 noch 34.22222 heraus,
sondern 33 und 34

Da das korrekte Ergebnis (welches aber so nicht berechnet wird)
33.722 wäre und 33.722 näher an 34 liegt (Rundung), wird wohl die
2. te Formel einen Tick besser sein.

von 1323 (Gast)


Lesenswert?

Wichtig ist auch die Rueckwaertsrechnung. Welche Baudrate kriegt man mit 
den gerundeten Zahlen ? Wenn die nicht innerhalb von 2% sind ist nichts.

von Falk B. (falk)


Lesenswert?

@ 1323 (Gast)

>Wichtig ist auch die Rueckwaertsrechnung. Welche Baudrate kriegt man mit
>den gerundeten Zahlen ? Wenn die nicht innerhalb von 2% sind ist nichts.

Das macht das Makro.

MFG
Falk

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.