Forum: Mikrocontroller und Digitale Elektronik Unnachvollziehbares Verhalten von AVR mit UART


von Buddl (Gast)


Lesenswert?

Hallo

Ich hoffe ihr könnt mir weiterhelfen.
Vielleicht hatte ja schonmal jemand ein ähnliches Problem.

Erstmal die Fakten:
Ich betreibe einen ATMega128 mit 14,7456MHz an der UART mit einem PC. 
Baudrate beträgt wahlweise 9600Baud, 19200Baud und 38400Baud. Als 
Pegelwandler kommt ein MAX3222 zum Einsatz. Der AVR wird mit 
BASCOM-Basic programmiert.

So nun folgendes:
Ich kann das Verhalten meines AVRs nicht nachvollziehen. Gehen wir vom 
einfachsten Fall aus. Ich sende im Hauptprogramm einfach immer wieder 
per PRINT Strings an den PC:

Do
Print "Hallo";
Loop

So etwa. Ankommen tut nur Schrott. Setzte ich ein Delay rein, etwa:

Do
Print "Hallo";
Waitms 8       'Delay um 8 Millisekunden
Loop

Funktioniert die Sache. Aber seit wann das?

Wenn ich nun ein komplexeres Programm aufsetze kann es sein, dass eine 
Zeit lang alles prima klappt. Es kann aber auch sein, dass am PC nur 
wirre Zeichen ankommen oder sich das ganze abwechselt, also:

Aktiviere Terminal: Einwandfreie Strings
Deaktiviere Terminal...
Aktiviere Terminal: Datenmüll
Deaktiviere Terminal...
Aktiviere Terminal: Einwandfreie Strings

Und obendrein ist das ganze auch noch mächtig baudratenabhängig. 
Manchmal gehts nur Baud9600, manchmal gehts sogar bis Baud38400, 
manchmal gehts mit überhaupt keiner...

Das kanns doch nicht sein. Das Ding stellt jeden Zufallsgenerator in den 
Schatten...

von Falk B. (falk)


Lesenswert?

@ Buddl (Gast)

>So etwa. Ankommen tut nur Schrott. Setzte ich ein Delay rein, etwa:

>Do
>Print "Hallo";
>Waitms 8       'Delay um 8 Millisekunden
>Loop

>Funktioniert die Sache. Aber seit wann das?

Nun, die erste Version läuft auch, aber sobald der PC nur einmal durch 
einen Übertragungsfehler oder eine Terminaldeaktivierung aus dem Tritt 
kommt, kommt er nie wieder rein. Dazu braucht er eine Pause von 
mindestens einem Zeichen. Dann kann der UART auf jeden Fall wieder 
resynchronisieren.

>Aktiviere Terminal: Einwandfreie Strings
>Deaktiviere Terminal...
>Aktiviere Terminal: Datenmüll

Klar, dein AVR sendet WIRKLICH ohne eine einzige Lücke Daten, darauf 
kann sich dein PC nicht synchronisieren.

MfG
Falk

von Buddl (Gast)


Lesenswert?

Ahh, macht Sinn.
Ich dachte, dass der PC so schnell wäre, dass er sich in einen 
bestehenden Datenstrom ohne Probleme "einklinken" könnte und dann durch 
Kontrollmechanismen die Übertragung aufrecht erhält (zum Beispiel alles 
was vor dem ersten Startbit übertragen wurde verfallen lassen).

Ich habe halt schon etliche AVRs programmiert und da bin ich nie auf 
dieses Problem gestoßen. Mag jedoch sein, dass ich diesmal über die 
Schwelle drüber bin, hatte derletzt einen AVR, der nur etwas geringer 
getaktet war und der konnte noch "am Stück" senden.

von Buddl (Gast)


Lesenswert?

Was ich noch sagen wollte:

Danke für die präzise und schnelle Hilfe. Jetzt weis ich mal in welche 
Richtung ich arbeiten muss. Das werde ich mal machen und schauen obs 
geht.

von Johannes M. (johnny-m)


Lesenswert?

Buddl wrote:
> Ahh, macht Sinn.
> Ich dachte, dass der PC so schnell wäre, dass er sich in einen
> bestehenden Datenstrom ohne Probleme "einklinken" könnte und dann durch
> Kontrollmechanismen die Übertragung aufrecht erhält (zum Beispiel alles
> was vor dem ersten Startbit übertragen wurde verfallen lassen).
Woher soll der PC denn bei einem praktisch kontinuierlichen Datenstrom 
wissen, welches Bit ein Startbit ist? Das wäre Zufall, wenn er sich da 
irgendwann wieder einklinkt...

von Falk B. (falk)


Lesenswert?

@  Buddl (Gast)

>Ich dachte, dass der PC so schnell wäre, dass er sich in einen
>bestehenden Datenstrom ohne Probleme "einklinken" könnte und dann durch

Der PC kann schnell sein wie er will. Das Prinzip des UART erlaubt das 
aber nicht.

>Ich habe halt schon etliche AVRs programmiert und da bin ich nie auf
>dieses Problem gestoßen. Mag jedoch sein, dass ich diesmal über die
>Schwelle drüber bin, hatte derletzt einen AVR, der nur etwas geringer
>getaktet war und der konnte noch "am Stück" senden.

Das Senden ist kein Problem, das richtige Empfangen ist es. 
Synchronisation heisst das Zauberwort.

MfG
Falk

von Buddl (Gast)


Lesenswert?

Vielen Dank für die Hilfe euch allen!
Hab jetzt überall ein Delay von 3ms drin und nun läuft die Sache 
bombenstabil.

Werd mich bei Zeiten auch mal mit dem UART-Protokoll auseinandersetzen, 
dann versteh ich das vielleicht mal von selbst ;)

von Peter D. (peda)


Lesenswert?

Es muß auch ohne Delay gehen.

Du mußt bloß zuerst das Terminalprogramm starten und dann den AVR 
einschalten.
Der PC muß die Chance haben, einmal das richtige Startbit zu erkennen.

Wenn dann allerdings irgendwann wieder Müll erscheint, stimmen die 
Baudraten nicht richtig. Dann sendet der AVR ein kleines bischen zu 
schnell und irgendwann verpaßt dann der PC das nächste Startbit.


Peter

von Buddl (Gast)


Lesenswert?

Bei dem Ding an dem ich arbeite ists nur so, dass es später über Funk 
laufen wird und sich das Terminal irgendwann einklinken wird. Verlohrene 
und unvollständige Daten sind also vorprogrammiert. Aber naja, 3ms kann 
ich noch entbehren, mehr dürfts allerdings echt nicht sein.

von Wolfram Q. (quehl)


Lesenswert?

ich habe das bei mir mal getestet.
ATMEGA32, 38400 baud, 8Mhz Takt, assemblerprogramm sendet ohne 
Unterbrechung daten an den UART. (Flaschenhals UART).

Wenn ich erst Mega einschalte und dann HTERM, sind die ersten 15 Bytes 
falsch. (4ms) nachfolgende sind dann richtig.

Wenn ich erst HTERM einschalte und dann Mega, sind die ersten Zeichen 
richtig. Nach ca. 6000 Zeichen fehlen einige Zeichen und dann geht es 
richtig weiter. (kein falsches Byte).
Das macht mir jetzt etwas Sorge, weil ich nicht weiß, woran das liegt. 
Ich vermute, daß das an Windows liegt. (Win98). Beim Schreiben von 
Texten hier hatte ich auch mehrmals schon eine Störung in der Anzeige, 
aber nach mehreren Sekunden wurde der geschriebene Text dann auch 
angezeigt. Ähnliche Störungen bei anderen Programmen.
Da meine Endanwendung ein PC DOS Assemblerprogramm ist, könnte es dann 
vielleicht sein, daß das richtig läuft. Aber das habe ich noch nicht 
programmiert.

mfg

von Falk B. (falk)


Lesenswert?

@ Peter Dannegger (peda)

>Es muß auch ohne Delay gehen.
>Du mußt bloß zuerst das Terminalprogramm starten und dann den AVR
>einschalten.
>Der PC muß die Chance haben, einmal das richtige Startbit zu erkennen.

Peter, das haben wir schon geklärt. Umfassend.

>Wenn dann allerdings irgendwann wieder Müll erscheint, stimmen die
>Baudraten nicht richtig. Dann sendet der AVR ein kleines bischen zu
>schnell und irgendwann verpaßt dann der PC das nächste Startbit.

Wenn der AVR zu schnell sendet verpasst der PC bestenfalls das Stop-Bit, 
aber keinesfalls das Startbit. Aber auch DAS sollte keinesfalls 
passieren, selbst bei geringfügig falschen Baudraten (<1%). Denn nach 
Ende des Stop Bits, genauer eigentlich nach Abtastung des Stop Bits in 
der Mitte sollte der UART wieder aus "Lauerstellung" für das nächste 
Startbit gehen und so problemlos einen lückenlosen Datenstrom endlos 
empfangen können.

Was ANDERES ist ein Echo im uC. Wenn der PC lückenlos Daten sendet, der 
AVR diese empfängt und sofort zurücksendet, dann kann es passieren, dass 
Bytes vom AVR verschluckt werden, und zwar dann, wenn der Takt vom AVR 
GERINGFÜGIGST zu langsam ist. Dazu braucht man keinen Fehler von -1%, 
-10ppm (ja zehn PPM) reichen aus. Das ist das klassische Problem 
plesiochroner Systeme.

Beispiel.

PC hat perfekte Baudrate von 9600 Baud.
AVR läuft mit -10ppm, also mit 9599,904 Baud

Wenn der PC nun 100.000 Zeichen lückenlos sendet (in 10,416666s), kann 
in der gleichen Zeit der AVR nur 99.999 Zeichen senden und wird das 
nächste verschlucken.

C’est la vie

@ Buddl (Gast)

>und unvollständige Daten sind also vorprogrammiert. Aber naja, 3ms kann
>ich noch entbehren, mehr dürfts allerdings echt nicht sein.

Hast du mein Posting mal in RUHE gelesen? EIN Zeichen reicht aus, macht 
bei 9600 Baud 1,04 ms.

@ Wolfram Quehl (quehl)

>Wenn ich erst Mega einschalte und dann HTERM, sind die ersten 15 Bytes
>falsch. (4ms) nachfolgende sind dann richtig.

Das ist korrekt. Wenn du aber ungünstige Zeichen sendest kann es 
passieren, dass der PC sich nicht synchronisieren kann, das ist 
prinzipbedingt.

>Wenn ich erst HTERM einschalte und dann Mega, sind die ersten Zeichen
>richtig. Nach ca. 6000 Zeichen fehlen einige Zeichen und dann geht es
>richtig weiter. (kein falsches Byte).
>Das macht mir jetzt etwas Sorge, weil ich nicht weiß, woran das liegt.
>Ich vermute, daß das an Windows liegt. (Win98). Beim Schreiben von

Möglicherweise verschlucht der Interrupt Zeichen. Probiers mal mit 1200 
Baud.

Allerdings besteht die minimale Chance, dass der UART doch bis zum Ende 
des Stopbits läuft und dann, weiss der Geier wieso, ein minimale Pause 
von vielleicht einem UART Takt (=16 fache Baudrate) einlegt. Damit 
verpennt er die Flanke vom Stopbit um 1/16 Bit. Das kann sich 
aufsummieren. Ich glaub das aber eher nicht (bis ich eindeutig vom 
Gegenteil überzeut werde).

MfG
Falk

von Wolfram Q. (quehl)


Lesenswert?

ich hab in Win98 den Takt von 38400 auf 115200 gestellt. Auf Hterm 
bleibt das auf 38400. Und nun habe ich beim Einlesen von 200000 Zeichen 
keinen Fehler drin. Ich hatte die Geschwindigkeit in Win98 mal auf 38400 
geändert, als ich noch nicht wußte, wie die Zusammenarbeit mit dem Mega 
geht. Beim Surfen ist das nicht aufgefallen. Jetzt wollte ich nur sehen, 
ob ich den Empfangspuffer vergrößern kann und da ist es mir aufgefallen. 
Der stand aber schon auf max.

@buddl
die 3ms sind eine unsichere Sache. Ich würde das Programm so ändern, daß 
erst nach einer Übertragung eines Startzeichens vom PC der Atmel mit der 
Übertragung beginnt.


mfg

von Falk B. (falk)


Lesenswert?

@ Wolfram Quehl (quehl)

>die 3ms sind eine unsichere Sache. Ich würde das Programm so ändern, daß

Sehe ich nicht so. Bei 9600 Baud sind das knapp drei Zeichenlängen. 
Reicht.

>erst nach einer Übertragung eines Startzeichens vom PC der Atmel mit der
>Übertragung beginnt.

Das nützt aber nix, wenn der UART auf Byteebene nicht synchronisiert. 
Das was du hier beschreibst ist schon eine Ebene höher, Layer 2. 
Praktisch braucht er bei gestörtem Übertragungskanal (Funk) beides.

MfG
Falk

von Wolfram Q. (quehl)


Lesenswert?

und warum synchronisiert der PC bei mir erst nach ca. 15 Zeichen? Wobei 
vorher auch schon richtige Zeichen ankommen, aber durch fehlende Zeichen 
kann ich das nicht als richtig anerkennen.

Klar, wenn eine Störung auftritt, gibt es immer Fehler. Da muß erst 
versucht werden, diese Fehler überhaupt zu erkennen. Dies wird 
wahrscheinlich erst in der weiteren Bearbeitung und 
Plausibilitätsprüfungen möglich sein. Und bis dahin ist die Störung 
vorbei. Dann muß das Programm erkennen, ab wann die Störung aufgetreten 
sein könnte und dann noch einmal lesen. Das ist sicher recht schwierig 
zu programmieren, darum sollte auch zunächst versucht werden, solche 
Störungen zu verhindern.
Ich weiß, leichter gesagt als getan.

mfg

von daniel (Gast)


Lesenswert?

Hallo,

sehr interresanter Beitrag. Es ist gut zu wissen und auch logisch das 
beim Uart nicht einfach so reingehoert werden kann in eine 
ununterbrochene Uebertragung. Sowie das Problem der klassischen 
pseliochonen Uebertragung.

Ein solches Verhalten kann ich auch in meinem System beobachten, es mir 
bis jetzt aber noch nicht erklaeren. Zu Beginn kommt keine Kommunikation 
zu stande, anschliessend schon. Auch ich verwende eine Baudratenquarz 
und die Kommunikation funktioniert einwandfrei. Aber zu Beginn des 
Programmes wird ein Text zum PC gesendet welcher im Terminal nicht 
angezeig wird, dann kommt eine Pause im Senden und anschliessend geht 
die ganze Sache wieder.

Vielen Dank fuer den wissenswerten Beitrag!

Daniel

von Andreas Paulin (Gast)


Lesenswert?

@ Daniel: Plesiochron... es heißt plesiochron *ggg

Klasse, dass Du diesen ollen Thread mal wieder vorgezogen hast. War 
nämlich auch für mich sehr informativ.
Möchte mich also in Daniels Sinn auch für das gute Posting bedanken.

Das Problem ist mir nämlich auch schon begegnet und man hatte es mit 
einem kleinen delay gelöst. Ohne jetzt genau zu erforschen, wieso.

Das heißt also im Fazit:
Wenn ich einen PC habe, dessen UART mit den üblichen 11.0592MHz oder 
14.7456MHz läuft, hat dieser eine exakte Baudrate.
Wenn mein externer µC mit 16.0000MHZ läuft, hat dessen UART zwangsläufig 
eine Abweichung davon um ein paar %.
Und diese Abweichung bringt also den Datenstrom bei KONTINUIERLICHER 
Datenübertragung durch kumulierende Bitphasenfehler zu Fall.

Gut zu wissen, wenns nächstesmal bei KB11,535 einen Unfall gibt :)








Mir haben die Glocken geklingelt. Das hatte ich in der Vergangenheit 
doch mal... da war doch mal was?
"... und immer nach ein paar KByte gibt's nen error!"
" da muss ein kleines delay rein, dann gehts einwandfrei.."

von spess53 (Gast)


Lesenswert?

Hi

>Und diese Abweichung bringt also den Datenstrom bei KONTINUIERLICHER
>Datenübertragung durch kumulierende Bitphasenfehler zu Fall.

Nein.

MfG Spess

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Andreas Paulin schrieb:
> Und diese Abweichung bringt also den Datenstrom bei KONTINUIERLICHER
> Datenübertragung durch kumulierende Bitphasenfehler zu Fall.
Nein. Es wird ja bei jedem Startbit neu synchronisiert.
Nur: dazu muß erst mal das Startbit erkannt werden.

Sieh dir mal das an:
Beitrag "Woran erkennt ein UART eigentlich das Startbit?"
Beitrag "Re: Das A und O des UART- Puffers"

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.