Forum: Mikrocontroller und Digitale Elektronik dynamische Baudrate


von Masl (Gast)


Lesenswert?

Hallo,

Zur Einstellung des UBRR-Registers des ATmega-USART gibts ja folgenden 
beliebten Codeschnippsel hier im Forum:
1
// Berechnungen
2
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
3
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
4
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
5
6
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
7
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
8
#endif

Nun würd ich aber gerne die Baudrate zur Laufzeit ändern können.
Also brauch ich eine Funktion welche mir aus einer Baudrate den 
UBRR-Wert errechnet.

Einfach nur obigen Präprozessorschnippsel auf "richtige" Anweisungen 
umändern wäre zwar einfach, würde aber unter anderem die Lib für 32-Bit 
Division nach sich ziehn.

Eine LookUp-Tabelle würde sich ja sogar im Datenblatt der ATmegas 
finden. Aber die zu übernehmen macht bei deren Größe wohl auch keinen 
Sinn.

Wie würdet ihr das lösen?

Viele Grüße,
Masl

von g457 (Gast)


Lesenswert?

> Wie würdet ihr das lösen?

Für festes F_CPU und veränderliche Baudrate: vom Präprozessor generieren 
lassen. Für feste Baudrate und veränderliches F_CPU: vom Präprozessor 
generieren lassen. Wenn beides veränderlich dann vermutlich der 
Einfachheit halber zur Laufzeit berechnen, sonst auch vom Präprozessor 
generieren lassen.

von amateur (Gast)


Lesenswert?

Vielleicht kannst Du die Tabellen stutzen. Ich kann mir kaum vorstellen, 
dass Du alle, möglichen Kombinationen brauchst.

- Dein Quarz ist, normalerweise, nicht austauschbar. Und wenn Du
  doch verschiedene Wackler einbauen musst, so kannst Du eine
  Fall-Zu-Fall-Tabelle abhängig von F_CPU implementieren. Deine
  Software muss ja sowieso wissen wie schnell sie ist.
- Ich glaube nicht, dass wirklich alle Geschwindigkeiten ausgewählt
  werden, schau mal in das Auswahlmenü deines Windoofs.
- Die Hälfte der Einträge ist sowieso für den Halbteiler.

von Peter II (Gast)


Lesenswert?

warum nicht einfach rechnen? Die Formel steht im Datenblatt dafür muss 
man zwar auf 32bit gehen aber ich denke das ganze wird nicht mehrmals in 
der Sekunde gemacht. Damit sollte die Zeit egal sein. Wenn es doch 
Zeitkritisch ist, kann man beim Programmstart sich seinen baudraten 
ausrechnen und dann nur noch eintragen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Masl schrieb:
> Eine LookUp-Tabelle würde sich ja sogar im Datenblatt der ATmegas
> finden. Aber die zu übernehmen macht bei deren Größe wohl auch keinen
> Sinn.

Wieso? Wieviele unterschiedliche Baudraten meinst Du denn unterstützen 
zu müssen? Müssen das mehr sein als 20?

von amateur (Gast)


Lesenswert?

Ich vergaß: Mul 8 und Div 8 dürften wohl durch einfache Schiebebefehle 
zu implementieren sein ... aber bei den Hauptdivision kommst Du wohl 
nicht um "echte" Division herum.
Wenn Du die 32-Bit Division nur für diesen Fall brauchst, schnapp' Dir 
die Sourcen der Bibliothek und extrahiere Dir das Teil. Mehr als 30 
Bytes werden das wohl nicht sein.

von Masl (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Wieso? Wieviele unterschiedliche Baudraten meinst Du denn unterstützen
> zu müssen? Müssen das mehr sein als 20?

Das nicht. Aber ich wär eben gerne flexibel, dazu fällt auch eine 
variable F_CPU.
Und 10 Baudraten bei 20 verschiedenen Quarzen ist auch schon ne menge 
Holz.

Das Umschalten ist auch nicht zeitkritisch, d.h. eine 32-Bit Berechnung 
wäre akzeptabel. Ich habe da eher Bedenken wegen der resultierenden 
Codegröße.

von g457 (Gast)


Lesenswert?

> Das Umschalten ist auch nicht zeitkritisch

..sach das doch gleich.. zur Laufzeit berechnen!

> Ich habe da eher Bedenken wegen der resultierenden Codegröße.

Optimierungen nicht ausschalten, dann sind keine Probleme zu erwarten.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Erzähl doch mal etwas mahr von dem was du vorhast, dann kan man besser 
helfen.

von Spess53 (Gast)


Lesenswert?

Hi

>Das nicht. Aber ich wär eben gerne flexibel, dazu fällt auch eine
>variable F_CPU.

Und wie teilst du dem Controller mit, welche Baudrate und welcher 
Controllertakt gerade angesagt ist? Ich sehe keinen reellen Nährwert in 
deinem Vorhaben.

MfG Spess

von amateur (Gast)


Lesenswert?

>Und 10 Baudraten bei 20 verschiedenen Quarzen ...
Mit einem Makro gesteuert durch F_CPU (oder wie das Teil bei deinem 
Compiler auch heißt) brauchst Du gerade mal 20 Bytes bzw. 10 Worte.
Ist das denn wirklich ein Problem?

Wohl gemerkt: Deine Software muss ja auf jeden Fall wissen welchen Takt 
Du ihr spendierst.
Daraus folgt: Ein Einfaches umlöten des Quarzes ist nicht möglich. 
Spielst Du aber die "passende" Software wieder ein, stimmt deine "neue" 
Tabelle auch wieder.

von Toni (Gast)


Lesenswert?

Mit variablen Baudrates zu arbeiten habe ich über eine
einfache automatische Baudratenerkennung gelöst.
Wird bei mir beim Programmstart aufgerufen.

Funktioniert ganz einfach:
Die Gegenseite sendet ein definiertes Zeichen, z.B. 0x30 oder 0x20.
Aus der Länge der zwei Bits (bei 0x30) oder dem einen einen Bit (bei 
0x20)
kann man die Baudrate ermitteln. Grundidee stammte ursprünglich
aus einer Intel-Anwendung für die 8051-Family. Funktioniert aber
auch bei anderen µC.

Diese Methode hat den Vorteil daß mit dem originalen Takt,
es wird die Anzahl der Takte pro Bit ermittelt, gerechnet wird.

von Masl (Gast)


Lesenswert?

Da stand ich wohl auf dem Schlauch.

F_CPU ist natürlich zur Compile-Zeit bekannt und unveränderlich. D.h. 
ich lasse den Präprozessor meine LookUp Tabelle berechnen, diese wäre 
dann insgesamt nur z.B. 10*2 Byte (UBRR hat 16 Bits) groß.

Das Ganze würde wohl in einem Array resultieren, das vom Präprozessor 
initialisiert wird?

von Fabian O. (xfr)


Lesenswert?

Masl schrieb:
> Das Ganze würde wohl in einem Array resultieren, das vom Präprozessor
> initialisiert wird?

Genau, und zwar sinnvollerweise in den Flash per PROGMEM.

von amateur (Gast)


Angehängte Dateien:

Lesenswert?

Ich habe vor ein paar Jahren, wegen Platzproblemen selber mal die 
Division extrahiert. Hatte sie noch.
Mit minimalen Anpassungen brauchst Du sie nur in eine .S-Datei packen 
und kannst glücklich werden. Die Aufrufkonventionen entsprechen denen 
des GNU-Compilers.
Damit dürftest Du auch die Baudrate eines 6,66MHz Quarzes berechnen 
können:-)

von Karl H. (kbuchegg)


Lesenswert?

Masl schrieb:

> Das Umschalten ist auch nicht zeitkritisch, d.h. eine 32-Bit Berechnung
> wäre akzeptabel. Ich habe da eher Bedenken wegen der resultierenden
> Codegröße.

Wenn du die ~30 Bytes nicht mehr hast, dann hast du sowieso gröbere 
Probleme.

von Werner (Gast)


Lesenswert?

Masl schrieb:
> Wie würdet ihr das lösen?

Woher kommt denn die Vorgabe für die Baudrate?
Die gängigen Fälle sind doch mit 10 Parametersätzen abgedeckt. Die 
Alternative wäre eine automatische Baudratenbestimmung per Timer, die 
dann auch beliebig krumme Werte frißt. Das kommt dann auf Prozessor, 
Taktfrequenz/Baudratengenerator, Baudratenbereich, verfügbare 
Prozessorzeit und nicht zuletzt auf das Datenübertragungsszenario drauf 
an.

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.