Forum: Mikrocontroller und Digitale Elektronik XC888 --> Empfang über UART


von Flipp (Gast)


Lesenswert?

Hey!

Ich habe hier ein kleines Eval-Board mit dem XC888 Controller drauf.
Meine Frage ist folgende:

Wenn ich ein Zeichen auf dem UART Empfange liegt es ja im Register SBUF 
bereit.
Was passiert nun wenn ich diesen noch nicht ausgelesen und ein neues 
Zeichen wird geschickt? Wird dieses dann einfach überschrieben? Da ich 
nach dem Empfang eines Zeichens noch ein bisschen was "machen" muss, ist 
mein Code unter Umständen noch nicht in der Lage dass nächste Zeichen 
auszulesen. Muss ich diese dann in einem Buffer zwischenspeichern oder 
was wäre ein Technik den Verlust von Daten da zu minimieren?

Viele Grüße

Flipp

von Peter D. (peda)


Lesenswert?

Flipp schrieb:
> Wird dieses dann einfach überschrieben?

Du hast 10 Bitzeiten Zeit, es abzuholen. Mit dem Stopbit des nächsten 
Bytes ist es weg.

Hast Du zu langsame Interrupts, mußt Du dem UART-Interrupt eine höhere 
Priorität geben.
Der UART-Interrupt schreibt nur die Bytes in einen FIFO, so daß man sie 
später in Ruhe auswerten kann.
Eine direkte Auswertung im Interrupt macht man üblicher Weise nicht.

von Flipp (Gast)


Lesenswert?

Hey,

vielen Dank für deine Antwort :)

Peter Dannegger schrieb:
> Der UART-Interrupt schreibt nur die Bytes in einen FIFO, so daß man sie
> später in Ruhe auswerten kann.

Ok, das heisst also in meiner Interrupt Routine von dem UART mache ich 
nichts anderes als die Empfangenen Daten in einen FIFO Speicher zu 
schreiben -> Dieser Speicher ist ein Buffer den ich mir selber anlege 
schätze ich mal...? (Sorry wenn ich so blöd nachfrage).
Das abarbeiten dieses Speichers übernehme ich dann im "normalen" 
PRogramm?

von Reinhard Kern (Gast)


Lesenswert?

Flipp schrieb:
> Dieser Speicher ist ein Buffer den ich mir selber anlege
> schätze ich mal...?

Das ist empfehlenswert - im UART ist meistens auch ein FIFO drin, aber 
von unterschiedlicher Länge, z.B. 16 Byte. Wenn du dir selbst eines 
anlegst, kannst du eine beliebige Länge wählen, und es muss auch kein 
FIFO sein, man kann je nach Protokoll auch einen (oder mehrere) 
Framebuffer verwenden: ich habe z.B. 256 Byte, weil eine Message maximal 
250 Byte hat und mit CR abgeschlossen wird - m.a.W. der Buffer wird 
einfach von Anfang an vollgeschrieben bis zum CR und dann (kopiert und) 
ausgewertet.

Trotzdem kannst du das Hardware-FIFO aktiviert lassen, das macht das 
Zeitverhalten robuster und ist ansonsten völlig transparent.

Gruss Reinhard

von Flipp (Gast)


Lesenswert?

Hey,

ok ich muss jetzt leider nochmal mit einer blöden Frage fortsetzen --> 
Gibt es auf dem XC888 überhaupt einen Hardware FIFO? Ich habe gerade mal 
das Datenblatt durchsucht und konnte dort nichts dergleichen finden. Im 
Endeffekt bleibt mir ja nichts anderes als einen eigenen in Software zu 
schreiben? Oder übersehe ich da irgendwas wichtiges gerade?

Viele Grüße

von Dietrich L. (dietrichl)


Lesenswert?

Flipp schrieb:
> FIFO

Das Ganze hängt auch vom "Protokoll" ab, wie die Kommunikation abläuft.

Wenn Du z.B. ein eindeutiges Startzeichen (z.B. ASCII "Stx") und eine 
begrenzte Nachrichtenlänge hast, ist es besser, in der ISR nach den 
Startzeichen zu suchen und anschließend die Daten in einem Array 
abzulegen. Auch Prüfung der Checksum (falls vorhanden) ist in der ISR 
sinnvoll.

In dem Fall ist in der ISR eine State-Machine praktisch, die mit einem 
Flag dem Hauptprogramm mitteilt, wenn ein bezüglich des Formates 
geprüfter und vollständiger Datensatz vorliegt. Das Hauptprogramm kann 
dann der Inhalt auswerten und entsprechend reagieren.

Gruß Dietrich

von Flipp (Gast)


Lesenswert?

Ja, das klingt gut, sowas in der Art habe ich mir auch gedacht - Die 
Nachrichtenlänge kann zwischen 2 und 6 Byte variieren. Aber selbst wenn 
ich meiner Hauptroutine erst die Nachricht übergeb wenn dies vollständig 
angekommen ist, muss ich ja davon ausgehen dass über den UART weiter 
Nachrichten übertragen werden. Sollte nun mein Hauptprogramm mit der 
Verarbeitung der Daten nicht nachkommen, so muss ich die vom UART 
Empfangenen Daten ja irgendwo zwischenspeichern. --> Also komme ich ja 
um einen Buffer bzw. FIFO Speicher wohl nicht herum...?

von Dietrich L. (dietrichl)


Lesenswert?

Flipp schrieb:
> Sollte nun mein Hauptprogramm mit der
> Verarbeitung der Daten nicht nachkommen, so muss ich die vom UART
> Empfangenen Daten ja irgendwo zwischenspeichern.

Wenn das nur kurzfristig ist, geht das. Aber wenn Du im Mittel oder über 
einen gewissen Zeitraum mehr Daten hast als Du verarbeiten kannst, ist 
was am Konzept faul...

Hast Du kein "richtiges" Protokoll? So was mit Frage-Antwort? Das wäre 
natürlich viel besser: Der nächste Datensatz wird erst geschickt, wenn 
Du den alten verarbeitet und quittiert hast. Dann würden auch 
Übertragungsfehler erkannt: kein richtiger Datensatz -> keine Quittung. 
Der Sender hat dann ein Time-Out beim Warten auf die Quittung und 
wiederholt die Daten.

Wie sinnvolle welcher Aufwand ist, hängt natürlich auch davon ab, wie 
wichtig die Daten sind, ob Übertragungsfehler erkannt werden sollen und 
ob auch mal was verloren gehen darf. Da haben sich schon viele Leute 
viele Gedanken gemacht - trivial ist das bei hohen 
Sicherheitsanforderungen bestimmt nicht.

Gruß Dietrich

von Flipp (Gast)


Lesenswert?

Hey,

ja also es gibt quasi ein kleines Protokoll. Es ist allerdings so --> 
Ich Empfange eine Nachricht, interpretiere die Daten und schicke dann 
z.B. einen Datensatz über den CAN Controller des µCs raus. Aber selbst 
wenn ich jetzt am Ende jeder (über den UART ankommenden) Nachrichten 
eine Bestätigung schicke, heisst das ja noch nicht das der 
Mikrocontroller beim Eintreffen der nächsten Nachricht schon wieder 100% 
da ist (vll. wurstelt er noch was an der CAN Nachricht rum).

Oder habe ich deine Antwort so zu verstehen, dass ich mein System so 
auslegen muss, dass derjenige der über den UART schickt irgendwie 
begrenzt werden muss, so dass er nie "zuviele" Nachrichten schickt ,dass 
quasi mein Buffer überlaufen würde?

von Dietrich L. (dietrichl)


Lesenswert?

Flipp schrieb:
> ja also es gibt quasi ein kleines Protokoll. Es ist allerdings so -->
> Ich Empfange eine Nachricht, interpretiere die Daten und schicke dann
> z.B. einen Datensatz über den CAN Controller des µCs raus. Aber selbst
> wenn ich jetzt am Ende jeder (über den UART ankommenden) Nachrichten
> eine Bestätigung schicke, heisst das ja noch nicht das der
> Mikrocontroller beim Eintreffen der nächsten Nachricht schon wieder 100%
> da ist (vll. wurstelt er noch was an der CAN Nachricht rum).

Aber wenn Du die Betätigung schickst, kann die ISR ja schon den nächsten 
Datensatz empfangen, während Du am CAN rummachst. Du bearbeitest die 
neue Nachricht dann halt erst, wenn der CAN fertig ist. Solange bekommt 
der Sender noch keine Bestätigung und wartet (die max. Wartezeit muss 
natürlich
 dazu passen).

> Oder habe ich deine Antwort so zu verstehen, dass ich mein System so
> auslegen muss, dass derjenige der über den UART schickt irgendwie
> begrenzt werden muss, so dass er nie "zuviele" Nachrichten schickt ,dass
> quasi mein Buffer überlaufen würde?

Das gilt natürlich immer: wenn Du mehr bekommst als Du verarbeiten 
kannst, läuft irgendwann jeder Puffer über - oder Du wirfst die Daten 
gleich weg und hast Datenverlust.
Hast Du aber eine Quittung im System, kann das nicht passieren.

Gruß Dietrich

von Reinhard Kern (Gast)


Lesenswert?

Flipp schrieb:
> dass derjenige der über den UART schickt irgendwie
> begrenzt werden muss

Logisch denken: es gibt nur 2 Möglichkeiten:

1. per Handshake bzw. Protokoll dafür sorgen, dass nur soviele 
Nachrichten verschickt werden, wie verarbeitet werden können.

2. Das System so planen, dass es egal ist, wenn Nachrichten 
verlorengehen. In den meisten Fällen ist das keine gute Idee. Aber bei 
Regelungen z.B. kann das funktionieren - wenn ein geänderter Sollwert 
nicht ankommt, dann kommt er eben mit der nächsten Nachricht.

(es gibt natürliche eine dritte Möglichkeit: das System funktioniert 
einfach nicht).

Es ist aber so gut wie nie sinnvoll, den Empfänger auf Dauer zu 
überfahren.

Gruss Reinhard

von Flipp (Gast)


Lesenswert?

Hey,

vielen Dank für die Antworten!!

Also ich denke ich werde es so machen, dass ich dem Sender am UART 
mitteile wenn ich wieder soweit bin Daten zu Empfangen. Ich denke das 
ist die unkomplizierteste und sicherste Lösung welche auch für meine 
Zwecke völlig ausreichend ist.

Ich danke euch nochmal für die schnelle und freundliche Hilfe!!!

Viele Grüße

Flipp

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.