PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Baudraten - #define xxx und einige Auswirkungen



oberallgeier
22.04.2009, 10:42
Hallo Alle,

möglicherweise habe ich eine Abhilfe gegen einige Baudratenfehler.

Ein immer wiederkehrendes Thema im Forum (hier nur EIN Beispiel) (https://www.roboternetz.de/phpBB2/viewtopic.php?t=47515) sind Probleme bei der Datenübertragung vom Controller über die RS 232. Grund ist, dass das enge Zeitraster der seriellen Übertragung von manchen Quarzen nicht einzuhalten ist.

... nicht einzuhalten ist? Sogar ATMEL mit seinen Formeln für die korrekte Einstellung der Oszillatorfrequenz und ein so kompetenter Ratgeber wie MikrocontrollerNet sind ähnlicher Meinung. (http://www.mikrocontroller.net/articles/AVR_Checkliste#.C3.9Cbertragungsprobleme_durch_fal schen_oder_ungenauen_Takt)

Frage: wozu haben wir einen Präprozessor - und eine einstellbare Oszillatorfrequenz für den USART?

Ich habe bei meinem Mega168 mit 20 MHz mit der "korrekten" Einstellung der Schnittstelle auf 115k2 Baud keine Chance, Daten über die RS232 an meinen PC bzw. an das Terminal von Br@y zu senden. Der Fehler ist einfach zu groß - wohl etwa bei -1,4 %. Was also tun? (Bitte fragt nicht, warum ich so aufs Tempo drücke - ich tendiere manchmal ein bisschen zu der Bleifußfraktion - sorry).

Klar - es dämmert schon jedem: einfach die "falsche" Bitrate einstellen. Ein kurzer Test am Controller ergibt folgendes:

//#define UART_BAUD_RATE 113600 // läuft ok
//#define UART_BAUD_RATE 115200 // läuft nicht
//#define UART_BAUD_RATE 116800 // läuft nicht

Frage: Ist diese simple Korrektur wirklich ein kleiner Fortschritt in unserem Bemühen um korrekte Einstellung der Baudrate bei "ungeeigneten" Quarzen?

vklaffehn
22.04.2009, 11:33
Moin!
Du meinst, quasi den Fehler von der ursprünglichen Baudrate abziehen? Oder hast Du das per Trial and Error ermittelt? Das Ganze käme mir sehr gelegen, da ich meistens alle IO's brauche und dann keinen Quarz dran habe.

MfG
Volker

P.S.:
Irgendwo habe ich letztens zufällig was gelesen, das jemand auf einem Pic mit Hilfe des Bresenhamalgorythmus einen genauen Timer verwirklicht hat, da sich der Fehler ja über die Zeit immer mehr gegen null bewegt, evtl. kann man damit ja auch was machen.

thewulf00
22.04.2009, 11:38
vklaffehn:
Rechne doch mal nach: 113600 ist 1.38% weniger von 115200, also hat ers ausgerechnet^^

oberallgeier
22.04.2009, 11:41
... Du meinst, quasi den Fehler von der ursprünglichen Baudrate abziehen ...Genau! Da leider die meisten Fehlerrechnungen nicht angeben, was der Grundwert ist (na ja, man kann sich bei "-1,4%" schon etwas denken) habe ich die 1,4 % mal auf die 115k2 drauf- und mal runtergerechnet. Nix Trial- und Error, das wäre doch etwas gegen mein Selbstbewusstsein.


... Das Ganze käme mir sehr gelegen, da ich meistens alle IO's brauche und dann keinen Quarz dran habe ...Wieweit das mit den relativ instabilen internen Oszillatoren geht, weiß ich nicht - dazu habe ich (noch) keine Tests gemacht. Die internen Takte bringen doch meist ihre Fehler durch ihre relativ starke Schwankungsbreite ein - und die kann ja durch eine konstante Korrektur nicht ausgeglichen werden. Aber DU darfst natürlich meinen Trick ohne Lizenzgebühren nutzen.


... jemand auf einem Pic mit Hilfe des Bresenhamalgorythmus ...... und bitte schreibe, wenn Du meinen Trick anwendest, immer dazu ©oberallgeier bzw: oberallgeieralgorithmus *ggggg* - aber nur wenn Du Zeit und Platz dazu hast.

PicNick
22.04.2009, 12:09
Ich hab mal eine liste für 20MHZ gemacht, welche Baudraten mit den möglichen UBRR-Werten (im relevanten bereich) möglich sind


UBRR Baudrate
12 96153,85
11 104166,67
10 113636,36
9 125000,00
8 138888,89
7 156250,00
6 178571,43
5 208333,33
4 250000,00
3 312500,00
2 416666,67
1 625000,00

christian_u
22.04.2009, 17:52
Das funktioniert aber nur solange du keine temeraturdrift wie beispielsweise bei den internen R/C Oszillatoren hast. oder man müsste über OSCAL mit Sync ytes in der Kommunikation und Checksummen ständig nachregeln.

thewulf00
22.04.2009, 18:35
Das funktioniert genausolang, wie es mit einem Baudratenquarz und der korrekten Baudrate funktionieren würde.

vklaffehn
22.04.2009, 18:36
Moin!
@thewulf00: Ist ja gut, jetzt sehe ich es auch, war doch grad erst aufgestanden.... :-)

@oberallgeier:
Den meinte ich :http://www.romanblack.com/one_sec.htm
Und für oberallgeieralgorithmus leg ich mir dann ein Tastaturmakro an :-)

Einen Versuch ist es auf alle Fälle Wert!

MfG
Volker

Besserwessi
22.04.2009, 18:44
Bei einer im Vergleich zum Systemtakt hohen Baudrate hat man das Problem, das man bei der USART nur ganzzahlige Werte für den Teiler einstellen kann. Man hat da also dann die Wahl zwichen ein paar Prozent zu hoch oder ein paar Prozent zu niedrieg. Da hilft dann auch keine andere Baudrate im Header, es sein denn die Gegenseite simmte auch nicht so ganz.

Das 2 te Problem ist, dass die Frequenz des internen Oszillators, nicht so genau ist. Da kann es dann helfen durch einen andere nominale Baudrate den richtigen Wert zu erreichen. Da hat man auch noch die alternative, elegantere Methode, den internen RC Oszillator mit dem OSCAL wert auf die richtige Frequenz zu bringen. Die kleine Verstimmung via OSCAL könnte man zumindestens ausnutzen, um die Rundungsproblem oben zu umgehen. Wenn ein 1 MHz Takt halt nicht geht für 19200 Baud, dann könnten 1.05 MHz eventuell gehen.

Der internen Takt ist aber leider abhängig von der Temperatur und Versorgungsspannung. Wenn die also stärker schwanken, kann man Probleme kriegen.

Der interne Oszillator bei den alten (z.B. At90S...) Chip war von der Tendenz her genauer als bei den neuen. Einige Sachen die früher mit dem internen Takt gingen gehen bei den neuen Chips eventuell nicht mehr zuverlässig.

Richard
22.04.2009, 19:07
Moin moin allerseits.

Ich habe vor langer Zeit einmal auf einen Pic eine veriable Baudrate
realisiert. Dazu mußte die Gegenstelle z.B. PC aber als erstes Byte
ein Hex F0 senden.

Ich habe dann einfach das Startbit abgewartet und dann auf die
Steigende Flanke von 1111_0000 gewartet und die Zeit gezählt.
Die Zeit / 4 /2 dann als Verzögerung fürs Einlesen/Senden damit
immer in der Mitte eines Bits gelesen wird. Das hat gut geklappt.

War natürlich in Assembler und hier nicht wirklich Pracktisch.

Aber man könnte auf diese Art einmal ein Byte + Start +Stop,
z.B. FF einlesen und die Zeit ermitteln. Dann kann man die
"echte" Baudrate/Abweichung errechnen.

Obwohl, solange ich mit einen externen Quarz arbeite klappt
das bei mir bisher. Intern ist echt Sch......:-(

Grüße Richard

oberallgeier
22.04.2009, 21:11
Ohhhh ohhhh, da habe ich also mit sehr wenig Sätzen gezeigt, wieviel ich von einer gar nicht sooo komplizierten Sache verstehe. Im Wesentlichen ist es die ganzzahlige Division - deren Eigenheiten ich übersehen hatte, weil ich bei meinen Überlegungen irgendwie nur Gleitkomma-Zahlen im Kopf hatte. Danke robert für die Tabelle - die mir die Augen schnell und recht weit geöffnet hatte. Danke Volker für den Hinweis auf und den Link zu Bresenham´s Algorithmus.

Ansonsten danke ich für Eure Nachsicht. Ich werde die UBRR-Rechnerei durcharbeiten ( unter anderem schon deswegen, um zu verstehen, wieso mein Beispiel mit den 115k2 am Terminal und den 113k6 in der #define funktioniert). Von der Beschäftigung mit der UBRR-Rechnerei hatte mich mein unbesorgter und unbekümmerter Umgang mit der Lib von PFleury bisher abgehalten. Das soll nicht heißen, dass ich die Schuld an meinem Unwissen jemand anderem in die Schuhe schieben will.

oberallgeier
23.04.2009, 13:13
Hallo,

ein bisschen bin ich weiter gekommen. Einmal mit meinem Verständnis zum Baudraten-Generator in ATMEL-Controllern. Und ein bisschen in meiner ursprünglichen Behauptung, dass man Baudraten doch optimieren kann (bitte versteht das nicht als Versuch nach dem Motto "ich will doch Recht behalten"). Danke jedenfalls für eure konstruktiven Hinweise zu meiner ursprünglich falschen Auffassung.

Zum besseren Verständnis des Ganzen habe ich mir zwei Rechnungen gemacht: die analytische und die synthetische. Die zugrundeliegenden Formeln stammen aus dem ATMEL-Doc, siehe Tabelle. Zuerst wurde auf der Basis von 20 MHz und der ganzzahligen Vorgabe des UBRR-Wertes eine theoretische Baudrate (mit Nachkommastellen, also RZ = reeller Zahlenwert) errechnet, wie dies PicNick schon getan hatte; Robert, nochmal danke dafür. Zur Zielbaudrate wurde der theoretische Fehler - Zielwert = 100 % - errechnet. Die Kombinationen mit den geringsten Fehlern im entsprechenden Baudratenbereich sind farbig unterlegt.

Danach wurde zu einer vorgegebenen Baudrate als #define xxx ein UBRR-Wert (RZ) errechnet. (Anmerkung: Bei der Berechnung fällt im vorliegenden Fall der Nachkommaanteil erst "zum Schluss" des Rechenganges an, es wird also kein Anteil unkontrolliert mitgeschleppt). Der als #def BD (#define Baudrate) vorgegebene Wert wird etwa so gewählt, dass er rund 0,5 (Nachkommaanteil wird bei der Rechnung im Praeprozessor abgeschnitten) über dem UBRR-Wert mit dem minimalen Fehler im entsprechenden Bereich liegt. So bekomme ich teilweise durch eine "falsche" Vorgabe (farbig unterlegt und farbige Schrift) einen minimalen Fehler.

Wieso? In der Zeile mit dem roten Marker sieht man, was unter den zugrunde gelegten Umständen bei 115k2 passiert: der Praeprozessor berechnet mit dem #define 115200 ein UBRR von 9 - die 0,85 fallen ja weg - und damit einen Fehler von 8,5 % über der Zielrate. Wenn ich im #define nun den Wert 111 000 schreibe, bekomme ich die theoretische Baudrate 113636 und damit einen Fehler von -1,36 %. Auch mein im Eingangsposting genannter #define 113600 ergibt noch ein UBRR von 10 - und damit -1,36 % - die Abweichung, mit der meine Controller-PC-Verbindung noch zurecht kommt. Auch ein #define 56k bringt bei einer Verbindung mit 56k 1,46 %, bei einer Verbindung mit 57k6 nur -1,36 % - - und so weiter. Ich hoffe, dass diese Rechnung dem einen oder anderen hilft - und dass meine Erläuterungen und Rechnungen verständlich (und diesmal richtig) sind.

............http://oberallgeier.ob.funpic.de/baud-01.gif

Volker: Dumm wirds natürlich bei den internen Oszillatoren. Dann kommen die Schwankungen oder ein Offset des internen Oszillators noch zu den hier genannten Abweichungen. Nach Murphy eben immmer (oder zumindest dann, wenns besonders stört) nach der falschen Seite. Also ist die genaue Kenntnis der Frequenz des internen Oszillators schon wünschenswert - ich weiß allerdings nicht, wie ich das 1. messen sollte und 2. wie ich das korrigieren könnte (zur Korrektur gibts doch irgendeine Speicherzelle - damit kenne ich mich leider nicht aus).

Viel Erfolg

PicNick
23.04.2009, 14:04
Man könnte den UART-Partner mitspielen lassen, der z.B permanent ein 0xC0 sendet.
durch Veränderung des UBRR wird man
ein 0x80 empfangen, ==> Rate/Osc zu schnell, UBRR zu klein
ein 0xE0 empfangen, ==> Rate/Osc zu langsam, UBRR zu gross.

oberallgeier
15.11.2011, 09:14
Vielleicht nicht ganz ohne Interesse zur Baudratentoleranz des FTDI.

Gute Toleranz des FTDI hatte ich schon hier vermutet (https://www.roboternetz.de/community/threads/49290-USB-gt-RS232-(TTL)-Wandler?p=474987&viewfull=1#post474987) und behauptet, "... dass der FT232 ziemlich fehlertolerant ist ..."

Mit meiner selbstgefertigten USB-UART-Platine (klick für Boarddesign) (https://www.roboternetz.de/community/threads/36416-RS232-Wandler-in-SMD?p=437181&viewfull=1#post437181) mit dem FT232 habe ich nun in den letzten Tagen wiederholt festgestellt, dass ich mit nem mega328/8MHz (interner !! Oszillator) bei 38,4 kBD rechnerisch zwar einen Fehler von -7% bzw. +8% (evtl. 12%) erhalte - WENN die 8 MHz stimmen. Da dieser Oszillator bekanntlich z.T deutlich abweicht, kanns mehr oder weniger sein. Trotzdem ist die Verbindung stabil und fehlerfrei. Bei 56k gibts dann erste Fehler.

Auf meinem aktuellen Steckbrettaufbau hatte ich die Frequenz des Quarzes nicht kontrolliert aber die UART mit 38400 Baud betrieben - und sie läuft zuverlässig. WinXP, Terminal von br @ y , meine oben genannte U S B-UART-Platine, 1,5 m Kabel Unitronic (LAPP) 4x0,14, ungeschirmt.

Dass ich mit der gleichen Platine und nem bequarzten m168/m328/20MHz problemlos 256 kBD fahre, hatte ich schon andernorts geschrieben.

Searcher
15.11.2011, 10:04
Also ist die genaue Kenntnis der Frequenz des internen Oszillators schon wünschenswert - ich weiß allerdings nicht, wie ich das 1. messen sollte und 2. wie ich das korrigieren könnte (zur Korrektur gibts doch irgendeine Speicherzelle - damit kenne ich mich leider nicht aus).

Hatte ich mal beim ATtiny24 (Datenblatt (http://www.atmel.com/dyn/resources/prod_documents/doc8183.pdf)) gemacht. Einen Timer auf PWM konfiguriert und mit Oszi an entsprechenden Pin gemessen. Im einem Programm das OSCCAL Register (Kapitel 6.5) sicherheitshalber zuerst ausgeben lassen. In anderer Programmversion dann in kleinen Schritten verändert. Vorsicht (denk ich) Datenblatt beachten. Im Anwendungsprogramm dann die Registerzuweisung mit dem guten gefundenen Wert als erste ausführbare Anweisung eingefügt. Das PWM Signal ist natürlich nur ein Teil des tatsächlichen Taktes und man muß zurückrechnen.

Man könnte zum Finden eines guten Registerwertes auch per Fuse den CKOUT Pin aktivieren (Kapitel 6.4) und dort den tatsächlichen Systemtakt messen.

Hab nicht gecheckt, ob das beim Mega168 auch so ist.

Gruß
Searcher