UART Baudrate richtig runden ( Regelung )

Gast #4867003
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
Gast #4867014
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.
#4867064
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.
Gast #4867717
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).
Gast #4867863
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.
Gast #4876330
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren