Forum: Compiler & IDEs UART Baudrate richtig runden ( Regelung )


von Thomas Nurul (Gast)


Lesenswert?

Guten Tag,

kenn jemand eine International geltende Regel zum Runden der UART 
Baudrate?

Im konkreten Fall komm als UBBR = Systemtakt / 16* Baud -1 = 218,5

Wird nun auf 219 aufgerundet oder auf 218 abgerundet indem die 
Nachkommastgelle einfach abgeschnitten wird?

Ich brauche eine Handfeste Regel.

Danke Gruß Thomas

von Peter II (Gast)


Lesenswert?

Thomas Nurul schrieb:
> Ich brauche eine Handfeste Regel.

dann schau in einem C buch nach. Dort steht je nach Datentyp drin wie 
gerechnet wird. Wichtig dazu ist dann die Operator-Reihenfolge.

> Systemtakt / 16* Baud -1 = 218,5


Systemtakt wird wohl int sein
dann erfolgt die Division durch 16 was als Int augeführt wird.
dann wird Baud multipliziert was auch als int gemacht wird
und dann wird die 1 abzogen.

Dabei kommt also überhaupt keine Nachkommestellen raus, weil alles als 
int gerechnet wird.

von Falk B. (falk)


Lesenswert?

@Thomas Nurul (Gast)

>kenn jemand eine International geltende Regel zum Runden der UART
>Baudrate?

Gibt es nicht, braucht auch keiner.

>Im konkreten Fall komm als UBBR = Systemtakt / 16* Baud -1 = 218,5

Jo mei, was passiert, wenn du auf 218 oder 219 rundest? Es entsteht ein 
sagenhafter Fehler von +/-0,228%.

UARTs sollten nach Möglichkeit mit weniger als +/-1% Fehler laufen, in 
bestimmten Fällen geht es auch bis +/-3%.

Siehe Baudratenquarz

>Wird nun auf 219 aufgerundet oder auf 218 abgerundet indem die
>Nachkommastgelle einfach abgeschnitten wird?

Als Integerrechung wird immer abgeschnitten.

>Ich brauche eine Handfeste Regel.

Du brauchst mal Entspannung.

von Oliver S. (oliverso)


Lesenswert?

Du denkst falsch rum...

Die Baudrate ergibt sich aus UBBR und dem Systemtakt, und ist immer 
ganzzahlig. Da kann und muß überhaupt nichts gerundet werden.

Oliver

von Karl M. (Gast)


Lesenswert?

Hallo Thomas,

ich programmiere gerade mit Assembler und schreibe deshalb:
1
.set F_CPU = 20000000
2
.set BAUDRATE = 115200
3
.set BAUD_SETTING = long( (F_CPU + BAUDRATE*4) /(BAUDRATE*8) -1 )

Hier wird der für das 16Bit Register UBBR der Wert BAUD_SETTING direkt 
berechnet und schon eine Aufrundung mit dem Faktor 0.5 einbezogen.
Wenn der Preprozessor Float unterschützt, schreibt man einfach:
1
const uint32_t F_CPU = 20000000UL;
2
const uint32_t BAUDRATE = 115200;
3
const uint16_t BAUD_SETTING = uint32_t((1.0 *F_CPU /8 /BAUDRATE +.5) -1);

Das Ergebnis ist in beiden Fällen BAUD_SETTING = (22 -1).

von Karl M. (Gast)


Lesenswert?

Nachtrag,

// UCSR0A - U2X0: Double the USART Transmission Speed
der Uart0 läuft im Modus UCSR0A.U2X0 = 1;

von Wolfgang (Gast)


Lesenswert?

Thomas Nurul schrieb:
> kenn jemand eine International geltende Regel zum Runden der UART
> Baudrate?

Belege das Baudratenregister so, dass der Baudratenfehler minimal wird.

Dafür braucht man nur ein bisschen Menschenverstand und keine 
internationale Vereinbarung.

von Wolfgang (Gast)


Lesenswert?

Falk B. schrieb:
> Als Integerrechung wird immer abgeschnitten.

... was einen aber nicht daran hindern kann, vor der Division zum 
Dividend die Hälfe des Divisors hinzu zu addieren. De facto läuft das 
dann etwa auf das Gleiche wie eine Rundung bei der Division reeller 
Zahlen hinaus.

von Hi-Tech-Progger S. (Gast)


Lesenswert?

Ich würde bei INT immer mit der etwas höheren Rate abtasten. Allerdings 
ist das nicht nötigt, wenn man es richtig programmiert: Man benutzt 
einen höher Aufgelösten Timer, von dem man immer nur die oberen BITs 
anschaut, um zu Teilen. So ist es möglich automatisch durch z.B. 133.1/3 
zu teilen. Der Zähler macht einmal 134 und zweimal 133.

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.