Hallo, ich habe mich ein bischen belesen zu UART/RS232. Einfache Frage: nehmen wir mal an, ein Sender sendet zum Ende jeder Sekunde 1 Byte. Der Empfänger fragt aber nur alle 5 Sekunden ab (4 Zeichen gehen verloren, absichtlich, Sender sendet redundant). Beim Empfänger wird nach dem ersten empfangenen Zeichen USR.RCX gesetzt. Das erste Byte steht dann in UDR. Es wird aber nicht abgeholt. Wird der Inhalt von UDR ersetzt a) wenn das zweite Zeichen komplett gesendet wurde, oder b) erst wenn UDR ausgelesen wird? Anders gefragt: Wenn der Sender 1 bis 10 sendet und der Empfänger bei Zeitpunkt 5,1s und 10,1s ausliest, wird er 5 und 10 auslesen oder 1 und 5? Oder noch was Anderes?
Das ist ne gute Frage. Ich fand solche Fragen immer spannend genug, dass ich mich hinsetzte und einfach mal ein Testprogramm geschrieben habe um rauszufinden was da wirklich abgeht. Anscheinend ist das heute aber nicht mehr modern.
Das UDR ist einerseits Hardware-gepuffert und muss andererseits ausgelesen werden, um Platz für ein neues Zeichen zu machen. Wenn im Puffer schon ein weiteres Zeichen wartet, wenn UDR gelesen wird, dann bleibt auch das RxC-Flag gesetzt. Wenn ein neues Zeichen ankommt und der Puffer bereits voll ist, dann wird das Buffer-Overflow-Bit-gesetzt. Grundsätzlich gilt: RxC bleibt gesetzt, solange noch ungelesene Daten vorhanden sind. Der Inhalt von UDR kann nicht ersetzt werden, wenn nicht gelesen wird.
Die saubere Methode ist, man liest den Puffer erstmal leer, wenn wieder was empfangen werden soll. Man könnte den Empfänger auch solange disablen. Aber das birgt die Gefahr, daß man in inmitten eines Bytes enabled und das dann Schrott ist. Man könnte aber auch ganz profan nen Interrupthandler aufsetzen. Bei schnarchlahmen 1 Byte/s ist die CPU-Last kleiner 0,00001%. Peter
Karl heinz Buchegger wrote: > Ich fand solche Fragen immer spannend genug, dass ich mich > hinsetzte und einfach mal ein Testprogramm geschrieben habe > um rauszufinden was da wirklich abgeht. Ich nicht. Ich programmiere einfach so, daß mich das nicht interessiert. Also entweder alles wegschmeißen, wenn ein Überlauf eintritt oder nen Interrupthandler, damit kein Überlauf eintritt. Peter
>Anscheinend ist das heute aber nicht mehr modern.
Dann bin ich wohl auch altmodisch ;)
Finde die Frage auch sehr interessant...
@Karl heinz Buchegger doch, das ist noch modern, aber ich habe hier gerade nur einen PC und könnte es erst am Wochenende ausprobieren; wollte allerdings schonmal weiter Programmteile vorbereiten, die auf das o.g. basieren.. Also wenn ich immer den Puffer leerlese (1 Byte gepuffert) könnte ich beim Zeitpunkt 5,1s "1-2" oder "1-5" erhalten.. Je nachdem, wie der Puffer gehandhabt wird..
ach ja, Interrupt kommt nicht infrage, weil in den 5 Sekunden eine zeitkritische Assembler-Routine läuft.
nixwisser wrote: > @Karl heinz Buchegger > > doch, das ist noch modern, aber ich habe hier gerade nur einen PC und > könnte es erst am Wochenende ausprobieren; wollte allerdings schonmal > weiter Programmteile vorbereiten, die auf das o.g. basieren.. Mir gehts ähnlich. Bin unterwegs und hab keine Hardware bei mir. Sonst hätte ich das schon längst mit einem Pgm ausprobiert. Ich finde die Frage nämlich wirklich spannend. Das sind nämlich meist die Kleinigkeiten, die man im Datenblatt nicht findet, so sie überhaupt dokumentiert sind. > Also wenn ich immer den Puffer leerlese (1 Byte gepuffert) könnte ich > beim Zeitpunkt 5,1s "1-2" oder "1-5" erhalten.. Je nachdem, wie der > Puffer gehandhabt wird.. Ich würds einfach so programmieren: an einen Eingang kommt ein Taster. Wird Taster gedrückt (PeDa Entprellung) wird UDR ausgelesen und Zeichen zurückgeschickt. Dann noch ein HyperTerm dran und dann wird gespielt: 2 Zeichen vom HT senden, Taste drücken und ablesen was als letztes aus UDR ausgelesen wurde.
>ach ja, Interrupt kommt nicht infrage, weil in den 5 Sekunden eine >zeitkritische Assembler-Routine läuft. Das ist eine Ausrede. Die zeitkritischen Routinen können selber Interrupts sein oder die anderen Interrupts temporär abschalten, damit am Timing nichts schief geht.
na toll.. ich programmiere Interrupts, um keine Empfangs-Zeichen zu verlieren, und schalte sie dann aus .. :-)
Alles eine Frage des Programmierstils. Auf Interrupts gänzlich zu verzichten, ist jedoch grob fahrlässig ;-).
Was machen denn deine "zeitkritischen" Routinen. Und warum sind die so zeitkritisch. Ein UART Empfangsinterrupt ist ja normalerweise ein ziemlich einfaches Biest, so dass ich mich schon wundere, dass dich diese ~10 Zyklen alle heiligen Zeiten in Bedrängnis bringen. Eventuell könnte man bei diesen Routinen ansetzen, so dass sich diese Frage gar nicht mehr stell und der UART Empfang ganz einfach über Interrupt läuft.
@ Karl heinz Buchegger (kbuchegg) >Das ist ne gute Frage. >Ich fand solche Fragen immer spannend genug, dass ich mich >hinsetzte und einfach mal ein Testprogramm geschrieben habe >um rauszufinden was da wirklich abgeht. >Anscheinend ist das heute aber nicht mehr modern. Wir sind hier im im Land der Philosophen ;-) In Ösiland gibts eher Ingenieure. Früher gabs auch mal Kunstmaler . . . duckundwech Falk
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.