Hi.
Gerade bin ich dabei ein System mit einer UART-Schnitstelle aufzubauen
was Folgend Anforderungen genügen muss:
-Baudrate während Laufzeit dynamisch im bereich 1000 bis 12000
Konfigurierbar
-Die Baudrate auf dem Bus soll selbst ermittelt werden. Dazu sendet die
Gegenstelle ein bestimmtes Zeichen, auf das ich mein Gerät einstellen
soll.
Nur steh ich irgendwie auf dem Schlauch wie ich das machen soll. Die
Baudraten müssen ja ohne allzu große abweichung erzeugt werden können.
Was ist denn da so ein maximum an Abweichtung? Und was passiert, wenn
die Gegenstelle 100 Zeichen nacheinander sendet. Muss ich mich dann
nicht irgendwie Nachsynchronisieren ? Mein System läuft gerade mit nem
ATMega@14,318 Mhz.
Die Baudratenerkennung muss ich ja wohl per Software machen. Und aus der
ermittelten Bitdauer, dann die Baudrate ausrechnen oder nicht ? Oder
gibts ne bessere Lösung, dass ich irgendwie den Takt dynamisch extern
erzeugen kann und dann den Uart per Software emulier. Weiss halt nicht
ob das mit der Performance dann hinhaut weil der Mega hat noch einige
andere Aufgaben.
Wie würdet ihr das machen ?
Viele Grüße
Jens
Hallo,
gibt es feste werte der Baud raten? welches Zeichen wird gesendet?
Warum wird die Baudrate gewechselt und wird das vorher angekündigt? Wird
das Erkenntung Zeichen solgange gesendet bis du was sendest oder wie?
Hi.
Das Gerät sollte sich auf möglichst alle Baudraten einstellen können
(sofern sowas überhaupt möglich ist ?) Es geht nur darum dass die
Gegenstelle die Baudrate bestimmt. Ich wecke sie per externem Signal
(Wake Up Line) auf und mit welcher Baudrate die Kommunikation läuft
bestimmt die Gegenstelle. Anhand eines Zeichens, aus der mein Gerät die
Baudrate erkennen soll. Die gesamte restliche Kommunikation soll
anschließend mit dieser Baudrate ablaufen.
@Vlad Tepesch: Irgendwie schreck ich von dem Konzept des SoftwareUARTs
zurück, weil ich damit CPU Zeit verschenk. Und eine voll ausgelastete
12000kbit Verbindung in Software is doch auch nicht soo Ressourcen
schonend !?
Wie sicher sind eigentlich die UARTS ? Wenn ich ne abweichung von 1% hab
und dann 10000 bits nacheinander Sende/Empfange is des doch ne enorme
Abweichung. Oder ist die Abweichung nur bis jeweils zum stoppbit
relevant ?
Diese Frage:
>die Gegenstelle 100 Zeichen nacheinander sendet. Muss ich mich dann>nicht irgendwie Nachsynchronisieren ?
draengt allerdings den Hinweis auf: Beschaeftige Dich erstmaln
Grundlagen der seriellen Kommunikation.
(syncron/asyncron/statbit/stoppbit...)
Gast
Jens S. schrieb:> @Vlad Tepesch: Irgendwie schreck ich von dem Konzept des SoftwareUARTs> zurück, weil ich damit CPU Zeit verschenk. Und eine voll ausgelastete> 12000kbit Verbindung in Software is doch auch nicht soo Ressourcen> schonend !?
da kenn ich mich nicht sogenau aus, aber vielleicht kann man die
Baudrate mit der SW-UART ermitteln und dann auf die passend
konfigurierte Hardware-UART umschalten.
Hi.
"Und was passiert, wenn die Gegenstelle 100 Zeichen nacheinander sendet.
Muss ich mich dann nicht irgendwie Nachsynchronisieren ?"
Guck mal hier:
www.chemgapedia.de/vsengine/vlu/vsc/de/ch/11/cmt/vlus/schnittstellen.vlu
.html
Und hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART
Und beim Klassiker:
http://de.wikipedia.org/wiki/EIA-232
"Die Baudraten müssen ja ohne allzu große abweichung erzeugt werden
können.
Was ist denn da so ein maximum an Abweichtung?"
Guck mal im Datenblatt vom ATMega16 auf den Seiten 168-171 nach. Dort
sind einige Fehlerrechnungen bei den möglichen Baudraten aufgelistet.
"Das Gerät sollte sich auf möglichst alle Baudraten einstellen können
(sofern sowas überhaupt möglich ist ?) Es geht nur darum dass die
Gegenstelle die Baudrate bestimmt."
Was ist den die Gegenstelle? Ein PC? Der kann wahrscheinlich eh nur die
gängisten Baudraten "bestimmen".
Wenn die Gegenstelle nur die gängigsten Baudraten (2400bd,4800bd,9600bd,
usw.) produziert, könntest du das so machen:
Die Gegenstelle sendet 3 oder mehr, sich möglichst stark von einander
unterscheidente Zeichen, die dem µC bekannt sind (bsp: '1','%','a').
Zwischen den Zeichen sollte eine Pause liegen, die größer ist, als die
langsamste Übertragung dauert. Danach stellst du die Baudrate im µC auf
den kleinsten, zu erwartenden Wert. Empfägt der µC nun ein Zeichen,
überprüfst du es jeweils mit jedem Prüfzeichen. Gibt es keine
Übereinstimmung, stellst du die Baudrate auf den nächstgrößeren Wert ein
usw. Wird nun vom µC eine '1' erkannt, muss das nachfolgende Zeichen ein
'%' sein. Ist es das nicht, veränderst du wieder die Baudrate usw.
Vieleicht hilft dir das ja etwas...
> Die Gegenstelle sendet 3 oder mehr
Das wird üblicherweise eher auf diese Art gemacht:
Die Gegenstelle sendet ein 0xAA, das ergibt dann dieses Bitmuster:
1
_______ _ _ _ _ __________
2
|_| |_| |_| |_| |_|
Mit einem Timer-Interrupt oder einem Capture-Compare lässt sich hier
einfach die eine Bitzeit ausmessen, und diese dann als
Berechnungsgrundlage für die Baudrate verwenden.
Lothar Miller schrieb:> Das wird üblicherweise eher auf diese Art gemacht:> Die Gegenstelle sendet ein 0xAA, das ergibt dann dieses Bitmuster:
Bei Geräten, die interaktiv über ein Terminalprogramm verwendet werden,
wird auch gerne 0x0A (LF) genommen, da sich das einfach via Tastatur
erzeugen lässt (Enter drücken). Das enthält dann zumindest in einer
Hälfte besagtes Bitmuster.
Andreas
Ebenfalls seit Jahrzehnten zur Baudraten- und Parametererkennung wird
die Zeichenfolge AT verwendet - das macht jedes serielle Modem mit
Hayes-Befehlssatz so.
Jens S. schrieb:> Und eine voll ausgelastete> 12000kbit Verbindung in Software is doch auch nicht soo Ressourcen> schonend !?
Naja voher hast du ja nur was von 12k gesprochen, eben ist deine
Geschwindigkeit um das 1000fache gewachsen!
bei 14Mhz ist beim ATmega sowieso bei 230k schluss.
Wie groß der Fehler sein darf liegt an der Anzahl der Bit die übertragen
werden. Nach der Start Flanke wird genau 1,5 Bitzeite gewartet (bei
einfacher Abtastung) und dann das erste Bit eingelesen. Danach wird
immer eine Bitzeit gewartet.
Beispiel Bitzeit ist 1us Empänger hat eine Abweichung von +5%
Sender 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5
Empfänger 1.55 2.60 3.65 4.7 5.75 6.8 7.85 8.9
man sieht das der Empfänger das letzte Bit erst kurz vor der nächsten
Flanke Sampeln würde, in diesem Fall würde es gerade noch gehen. Das
liegt aber daran das der Sender keinen Fehler hat und die Flanke
unendlich steil ist.
Praktisch liegt der maximale Fehler dann so bei 2%. Das würde in deinem
Zenario bedeuten das du die Werte in einem 2% Raster abtasten müsstet,
wenn du nicht die Bitzeit bestimmen kannst.
Also UART auf 1000 Stellen einige Bytezeiten abwarten nächste Baudrate
1020 wieder warten usw. Bis 12k müsstet du 123 Werte ausprobieren bis
12000k wären es 476 Werte.
Mir erschliest sich noch nicht ganz warum der Sender überhaupt krumme
Werte haben soll und warum jedesmal ein andere genommen wird...
Normalerweise gibt die Übertragungstrecke und das langsamste Gerät die
Gewindigkeit vor (bzw. danach hat sich der Entwickler zu richten)
Power schrieb:> ...> man sieht das der Empfänger das letzte Bit erst kurz vor der nächsten> Flanke Sampeln würde, in diesem Fall würde es gerade noch gehen. Das> liegt aber daran das der Sender keinen Fehler hat und die Flanke> unendlich steil ist.
Das schlimmste daran ist, dass eine erneute Synchronisation erst
erfolgen kann, wenn mindestens 2 (oder waren es 1.5?) Bitzeiten nichts
gesendet wurde.
Das heißt, selbst wenn man nur zum Beispiel 0,3% Fehler hat, aber einige
Kilobyte an Daten in einem Block schickt (ohne Pause), die letzten Daten
verschandelt werden.
Man kann auch nach dem dann schlimmstenfalls verkürzten Stopbit noch
syncronisieren. Wie lange die Pause zur syncronisation sein muß, hängt
von der UART ab, ein etwas verkürztes Stopbit sollte bei einer guten
Implemantation keine Problem sein. Dass mehr als 1/2 Bitzeit
ausgeglichen wwerden kann würde ich nicht von jeder UARt erwarten.
Mehr als 1 Stopbit zur Syncronisation ist also nicht immer nötig, kann
aber helfen wenn der Takt des Senders deutlich zu schnell ist im
vergleich zum Empfäger.
> Oder ist die Abweichung nur bis jeweils zum Stoppbit relevant ?
Ja, dafür sind Start- und Stopbit bei normaler asynchroner (das A in
UART) Kommunikation da.
Bei synchroner Kommunikation mit einem USART sieht es anders aus, aber
auch da wird normalerweise auf die eine oder andere Art alle paar Bits
nachsynchronisiert (z.B. Einfügen eines 0-Bits nach fünf 1-Bits bei
HDLC).
Juergen schrieb:>> Oder ist die Abweichung nur bis jeweils zum Stoppbit relevant ?>> Ja, dafür sind Start- und Stopbit bei normaler asynchroner (das A in> UART) Kommunikation da.
Und was ist, wenn kurz vor dem Stoppbit ein Datenbit kommt mit dem
gleichen Pegel, wie das Stoppbit? Oder kurz nach dem Startbit ein Bit
auch mit dem gleichen Pegel wie das Startbit? Dann ist keine
Synchronisation möglich, da die UART nicht weiß, wo das
Stoppbit/Startbit anfängt und wo es aufhört.
Das heißt beim Senden eines riesigen Datenblocks, wird der Takt am
Anfang gestartet (sobald die Flanke vom Startbit erkannt wird) und läuft
von da an, mit der eingestellten Baudrate und dem dazugehörigen
Baudratenfehler. Und bei irgendeinem Bit ist die absolute Abweichung
halt so groß, dass ab diesem Bit der Rest falsch eingelesen wird.
>Bei synchroner Kommunikation mit einem USART sieht es anders aus, aber>auch da wird normalerweise auf die eine oder andere Art alle paar Bits>nachsynchronisiert
Nee, bei synchroner Kommunikation wird der Takt mitgeliefert!
Simon K. schrieb:> Das heißt beim Senden eines riesigen Datenblocks, wird der Takt am> Anfang gestartet (sobald die Flanke vom Startbit erkannt wird) und läuft> von da an, mit der eingestellten Baudrate und dem dazugehörigen> Baudratenfehler. Und bei irgendeinem Bit ist die absolute Abweichung> halt so groß, dass ab diesem Bit der Rest falsch eingelesen wird.
Genau auf das Wollt ich hinaus...wenn ohne Pause gesendet wird. Lässt
sich die Fehlinterpretation nicht vermeiden ? Das Teil sollte schon
sicher funktionieren.
Warum das Gerät mit allen Baudraten zurecht kommen sollte ? Ganz
einfach...Es geht um eine art Wartungsgerät. Und das wird an die
unterschiedlichsten Automaten angeschlossen...Und diese Automaten haben
unterschiedlichste Baudraten. z.B. n 14 Mhz Quarz an nem µC und dann
halt die Baudrate so hingebogen dass man sich nicht mit Abweichungen
rumquälen muss...
Es gab schon son Gerät (wie zuverlässig das ist, keine
Ahnung)...jedenfals befindet sich auf der Platine eine PLL, die wenn ich
es richtig gesehen hab, nur an nem µC dran hängt..könnt das damit was zu
tun ham ? Am Uart hängt die PLL nicht wenn ich alles richg verfolgt hab.
Übrigens danke an Alle für die vielen Beiträge :)
Jens S. schrieb:> Simon K. schrieb:>> Das heißt beim Senden eines riesigen Datenblocks, wird der Takt am>> Anfang gestartet (sobald die Flanke vom Startbit erkannt wird) und läuft>> von da an, mit der eingestellten Baudrate und dem dazugehörigen>> Baudratenfehler. Und bei irgendeinem Bit ist die absolute Abweichung>> halt so groß, dass ab diesem Bit der Rest falsch eingelesen wird.>> Genau auf das Wollt ich hinaus...wenn ohne Pause gesendet wird. Lässt> sich die Fehlinterpretation nicht vermeiden ? Das Teil sollte schon> sicher funktionieren.
Korrekt. Ist halt eine schwäche der UART. Habe selber letztens versucht
mit vollen 3MBPS des FT232 in einen ATxmega zu schreiben (dank DMA kein
Problem), leider läuft der XMega mit 32MHz und der Fractional Baud Rate
Divider hilft mir in dem "oberen Baudratengebiet" nicht mehr viel. Aber
selbst bei 0,5% (sowas um den Dreh) Fehler, konnte ich keinen 4 Kilobyte
Block übertragen ohne Fehler. Ich habe dann 2MBPS genommen, das lässt
sich "ohne Fehler" aus den 32MHz erzeugen, damit geht sogar 8kB noch
problemlos. Man hat halt dann nur die Ungenauigkeit des Quarzes drin.
also 50 oder 100 ppm oder was das regulär sind.
Bei deiner variablen Baudrate geht das natürlich nicht.
Jens S. schrieb:> @Vlad Tepesch: Irgendwie schreck ich von dem Konzept des SoftwareUARTs> zurück, weil ich damit CPU Zeit verschenk.
Die Autobaud-Funktion liefert nur nen Zahlenwert zurück. Ob Du damit
dann ne SW- oder HW-UART initialisierst, ist schnurzpiepegal.
Bei der HW-UART mußt Du eben noch durch 16 teilen (4* Schieben).
Danach muß dann die Gegenstelle mindestens ein Zeichen senden, was nur
eine 1-0 Flanke (Startbit) enthält (z.B. 0xFF) und Du bist synchron.
Peter
Simon K. schrieb:>>> Das heißt beim Senden eines riesigen Datenblocks, wird der Takt am>>> Anfang gestartet (sobald die Flanke vom Startbit erkannt wird) und läuft>>> von da an, mit der eingestellten Baudrate und dem dazugehörigen>>> Baudratenfehler. Und bei irgendeinem Bit ist die absolute Abweichung>>> halt so groß, dass ab diesem Bit der Rest falsch eingelesen wird.
Nein eine UART synconisiert sich bei jedem Wort (Byte) neu.
Beim ersten fallenden Flanke geht das Wort los und dann werden soviele
Bit eingelesen bis ein Wort voll ist. Beim ATmega kann man 5-9 Bit
einstellen, wenn das letzte Bit gesampelt wurde wird das Wort in das
Inputregister Kopiert. Jetzt wird noch das Stopbit(s) gesampelt und
sofort danach der Eingang für das nächste Wort freigeschaltet.
Das alles kann man hier:
http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf
auf den Seiten 157-158 nachlesen.
Es hilf mauch manchmal einfach am Sender 2 Stopbits einzusellen und am
Empfänger 1. Dann sollte der Fall das der Empfänger den Sender über
nicht mehr auftreten. Das kann bei einem langen Burst passieren. Der
Empfänger sampelt gerade das letzte Stopbit und die Startbedingung
"fallende Flanke" wird nicht erkannt. Dann wird irgendein Bit
zwischendrin als Startbedingung genommen und man bekommt nur noch Müll.
Blöcke müssen immer durch ein Idle Time getrennt werden die länger ist
als ein Wort.
Simon K. schrieb:> Das schlimmste daran ist, dass eine erneute Synchronisation erst> erfolgen kann, wenn mindestens 2 (oder waren es 1.5?) Bitzeiten nichts> gesendet wurde.> Das heißt, selbst wenn man nur zum Beispiel 0,3% Fehler hat, aber einige> Kilobyte an Daten in einem Block schickt (ohne Pause), die letzten Daten> verschandelt werden.
Ähm, nein.
Die Synchronisation des Bit-Taktes kann (und wird) bei jeder Flanke im
Signal erfolgen, und durch das Start- und das/die Stopbit(s) wird
sichergestellt, dass jedes übertragene Byte mindestens eine Flanke
enthält. Der kumulierte Fehler erreicht dann bei 1% Baudratenabweichung
und 8N1-Format garantiert höchstens 10% einer Bitzeit (durch
Implementierungsdetails wie die von vielen UARTS gemachte diskrete
Abtastung mit dem 8- oder 16-fachen Bittakt kann das noch geringfügig
mehr werden, aber nicht viel), egal wieviele Bytes in direkter Folge
gesendet werden.
Auf Lücken im Datenstrom angewiesen ist nur die Byte-Synchronisation,
ein UART kann sich also nicht ohne weiteres "mittendrin" auf einen
permanent laufenden Datenstrom aufschalten. Für die Synchronisation der
Bytegrenzen ist aber eine Lücke von mindestens einem Bit mehr als einem
kompletten Byte nötig, also bei 8N1 muss mindestens 11 Bitzeiten lang
Pause sein.
Wenn das so wäre wie du denkst, dann würde die kontinuierliche
Übertragung nicht erst bei einigen kB zusammenbrechen, sondern schon
viel, viel früher, schon nach gerade mal 34 Bytes hätten sich deine 0,3%
zu einem kumuliertem Fehler von mehr als 100% der Bitzeit aufsummiert.
Andreas
Andreas Ferber schrieb:> Die Synchronisation des Bit-Taktes kann (und wird) bei jeder Flanke im> Signal erfolgen, und durch das Start- und das/die Stopbit(s) wird> sichergestellt, dass jedes übertragene Byte mindestens eine Flanke> enthält.
Dann habe ich das Prinzip doch noch nicht verstanden. Hatte das Problem,
was ich hatte mit großen Blöcken darauf zurückgeführt.
Ich hab gerade noch was geschrieben, weil mir dann ein paar Sachen nicht
klar waren, hab aber dann erst drüber nachgedacht und du hast natürlich
Recht. Die Bitsynchronisation braucht natürlich nur Flanken.
Da es hier um Auto-Baud ging, habe ich beide Sachen vermixt. Für
Autobaud braucht man ja auf jeden Fall ein 1-Bit was von 2 Null-Bits
umgeben ist (oder andersherum) um auf die Baud-Rate schließen zu können.
Und DAS geht nicht, wenn man Einen ganzen Block aus zum Beispiel 0xF0
Bytes sendet. Aber das war ja vorher schon klar (hoffe ich).
Entschuldigt die Verwirrung! ;-)