Forum: Mikrocontroller und Digitale Elektronik UART RX Interrupt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Zo R. (hsch1978)


Lesenswert?

Hallo,

für eine Anwendung wird ein ARM Cortex M33 Mikrocontroller eingesetzt.
Als Kommunikationsschnittstelle wir die UART verwendet. Die UART 
Kommunikation erfolgt nicht drahtgebunden sondern optisch. Dies bedeutet 
zuerst wird ein Vorspanntelegramm mit 500 bytes (jedes Byte hat den Wert 
0x55) gesendet. Sobald ein byte mit diesem Muster erkannt wird, wird 
dies als Vorspanntelegramm erkannt und die weiteren empfangen Bytes 
sollten von dem Empfangsinterrupt eigentlich ignoriert werden. Dies 
passiert allerdings nicht so wie es sein sollte. Der Empfangsinterrupt 
sollte deaktiviert werden, wenn ein Muster erkannt wird. Allerdings 
sollte nach dem Vorspanntelegramm wieder gewartet werden bis das 
eigentlich Telegramm vom Mikrocontroller empfangen werden kann. Ich 
bräuchte diesbezüglich Untersützung was ich für meine Implementierung 
auf der Mikrocontrollerseite beachten müsste damit die Kommunikation 
erfolgreich funktioniert.

: Bearbeitet durch User
von Christian (christiankpunkt)


Lesenswert?

Wenn die Hardware-UART im M33 keine Möglichkeit sieht, die Präambel 
auszufiltern, muss du das in Software machen.

Das heißt im Interrupt-Handler jedes 0x55 ignorieren bis was anderes 
kommt.

von Zo R. (hsch1978)


Lesenswert?

Ok es kann aber auch sein, dass statt den 0x55 x 500bytes auch 0xAA x 
500 bytes empfangen werden obwohl 0x55 x 500 bytes versendet wurden.

Und was sollte ich tun wenn folgendes passiert:
Der Mikrocontroller erkennt, dass das 2. empfangene Byte 0x55 ist. 
Trotzdem werden die anderen bytes im UART RX Interrupt empfangen.

: Bearbeitet durch User
von Εrnst B. (ernst)


Lesenswert?

He S. schrieb:
> Ok es kann aber auch sein, dass statt den 0x55 x 500bytes auch 0xAA x
> 500 bytes empfangen werden obwohl 0x55 x 500 bytes versendet wurden.

Wie soll das über den UART gehen? Start/Stop-bits, Parity-Bit?

von Christian (christiankpunkt)


Lesenswert?

Stimmt, wenn das (0)10101... Muster ohne Stoppbits gesendet wird, wird 
die URAT-Hardware solange im Fehlerzustand bleiben.

RX-Interrupts werden dann auch nicht kommen.

von Zo R. (hsch1978)


Lesenswert?

UART Settings: Databits:8, Stopbit: 1, Paritybit: Even

: Bearbeitet durch User
von Zo R. (hsch1978)


Lesenswert?

Was sollte ich in der UART Library tun wenn ein Muster 0x55 erkannt 
wird?
Jedes weitere byte mit 0x55 muss eigentlich ignoriert werden.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> für eine Anwendung wird ein ARM Cortex M33 Mikrocontroller eingesetzt.
> Als Kommunikationsschnittstelle wir die UART verwendet. Die UART
> Kommunikation erfolgt nicht drahtgebunden sondern optisch.

Das gab es schon mal, nannte sich IrDa. Nutzt ihr dessen Grundlagen? Das 
solltet ihr.

https://de.wikipedia.org/wiki/Infrared_Data_Association

> Dies bedeutet
> zuerst wird ein Vorspanntelegramm mit 500 bytes (jedes Byte hat den Wert

Naja, ob das so direkt so einfach funktioniert? Damit der UART 
synchronisieren kann, braucht der auch ein paar Pausen. Wenn man 
lückenlos 0x55 sendet, fehlen die.

> Sobald ein byte mit diesem Muster erkannt wird, wird
> dies als Vorspanntelegramm erkannt und die weiteren empfangen Bytes
> sollten von dem Empfangsinterrupt eigentlich ignoriert werden. Dies
> passiert allerdings nicht so wie es sein sollte.

Das liegt dann wohl an eurer Software.

> Der Empfangsinterrupt
> sollte deaktiviert werden, wenn ein Muster erkannt wird.

Wieso? Warum soll dann ohne UART RX Interrupt gearbeitet werden?

> Allerdings
> sollte nach dem Vorspanntelegramm wieder gewartet werden bis das
> eigentlich Telegramm vom Mikrocontroller empfangen werden kann.

Naja. Was heißt warten?

> Ich
> bräuchte diesbezüglich Untersützung was ich für meine Implementierung
> auf der Mikrocontrollerseite beachten müsste damit die Kommunikation
> erfolgreich funktioniert.

Es braucht vermutlich keine 500 Bytes, um den UART zu synchronisieren. 
Das kommt aber auch auf den Empfänger an. Ist eure optische Übertragung 
per Lichtwellenleiter oder Freiraum? Bei letzterem kann man nicht 
einfach naiv das UART Signal mit einer LED senden, da spuckt das 
Umgebungslicht rein. Darum auch der Hinweis auf UART.

von Zo R. (hsch1978)


Lesenswert?

WIr benutzen kein sichtbares Licht sondern Infrarot.
Das Vorspanntelegramm besteht aus 500 bytes. Diese werden nicht mit 
Pausen versendet.

von Harald K. (kirnbichler)


Lesenswert?

Wie auch immer, der UART_Rx-Interrupt ist der falsche Ort, um Deine 
selektive Datenbehandlung durchzuführen.

Lass die UART ihre Bytes empfangen, und wirf sie in Deiner Hauptschleife 
oder was auch immer Du da für ein Programmkonstrukt verwendest, wieder 
weg.

von Zo R. (hsch1978)


Lesenswert?

Ok, was sollte ich tun? Verstehe den letzten Beitrag nicht.

Ich weiß echt nicht mehr weiter, wie das ganze nun zum Laufen bringen 
kann.

: Bearbeitet durch User
von Jens M. (schuchkleisser)


Lesenswert?

Will da etwa einer sein Aufgabenblatt gelöst haben?
Sowas denkt man sich doch nicht aus wenn man nicht schon ne Idee hat wie 
man das realisiert....
Und es ist auch nicht allzu schwer, ein paar IFs zusammenzukloppen um 
beliebig viele 0x55s wegzuwerfen bis das erste nicht-0x55 kommt.
Und immer schön daran denken, das der Puffer nur eine begrenzte Größe 
hat, von wegen Buffer Overflow und so...

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> WIr benutzen kein sichtbares Licht sondern Infrarot.

Auch das kann man über LWL senden.

> Das Vorspanntelegramm besteht aus 500 bytes. Diese werden nicht mit
> Pausen versendet.

Das kann eines der Probleme sein. Ist aber ganz sicher nicht das 
Einzige. Zuerst sollte man sich mal das Ausgangssignal des Empfängers 
auf einem Logicanalyzer anschauen.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Ok, was sollte ich tun? Verstehe den letzten Beitrag nicht.
>
> Ich weiß echt nicht mehr weiter, wie das ganze nun zum Laufen bringen
> kann.

Tja, da hat wohl einem Anfänger einen ganz schön großen Brocken 
aufgeladen.
Der UART-RX Interrupt bleibt IMMER an! In dem läuft eine passende 
Statemachine, welche die empfangen Daten prüft und die Synchrondaten 
wegwirft, die Nutzdaten aber in einen Puffer, ggf. FIFO schreibt. 
Eine weitere State machine läuft im Hauptprogramm und dekodiert die 
Daten.

von Zo R. (hsch1978)


Lesenswert?

Ok Danke für eure Rückmeldungen.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

He S. schrieb:

> Das Vorspanntelegramm besteht aus 500 bytes. Diese werden nicht mit
> Pausen versendet.

Wenn Du an einem Pin Folgen von High und Low mit etwa einem 
Tastverhältnis von 1:1 ohne Pausen bekommst, dann ist es schlicht und 
ergreifend keine UART und dem entsprechend ist das Peripheral falsch 
gewählt. Dann bleibt Dir eigentlich nichts anderes über, als den Pin 
abzutasten und mit Software auszuwerten.

von Peter D. (peda)


Lesenswert?

He S. schrieb:
> zuerst wird ein Vorspanntelegramm mit 500 bytes (jedes Byte hat den Wert
> 0x55) gesendet.

0x55 ist ja nun das absolut dämlichste Byte zur Synchronisation.
Mit Start und Stop-Bit ist das eine einzige 1-0-Folge, ohne jede Chance, 
eine verlorene Synchronisation zu beenden. Wer denkt sich denn bloß 
sowas aus.
Eine reale Chance auf Synchronistation hat eine HW-UART nur bei Bytes 
mit keiner weiteren 1-0-Flanke nach dem Startbit, z.B. 0x00, 0x80, 0xC0, 
0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF.
Oder man sendet mit 2 Stoppbits, dann fängt sie sich auch irgendwann 
wieder.

He S. schrieb:
> Der Empfangsinterrupt
> sollte deaktiviert werden, wenn ein Muster erkannt wird.

Das sollte man auf keinen Fall tun, denn dann läuft der UART-Puffer 
über. Die UART zu disablen, ist auch ganz schlecht. Dann fehlt nämlich 
die Synchronisation auf das Startbit. D.h. die UART kann beim wieder 
Einschalten auf eine 1-0-Flanke in den Datenbytes einrasten.

Optimal setzt man daher eine Statemaschine auf, die in diesem Zustand 
alle Bytes abholt und verwirft.

von Harald K. (kirnbichler)


Lesenswert?

Die Kombination von 8n1 und 0x55 im Dauerfeuer ist nicht die hellste 
Torte unter der Kerze.

Macht aber nichts, man wartet halt solange ab, bis der Schwall aus 0x55 
bzw. 0xAA vorbei ist.

Die Beschreibung lässt erahnen, daß das sendende Gerät eine Pause 
zwischen ihrem Datenschwall und dem Nutztelegramm macht.

von Bruno V. (bruno_v)


Lesenswert?

He S. schrieb:
> Vorspanntelegramm mit 500 bytes (jedes Byte hat den Wert
> 0x55) gesendet.

War das mal Funk? 500 bytes machen bei einem Uart 0 Sinn.

Jedenfalls wird es hier noch andere, uns unbekannte Restriktionen geben. 
Erzähl uns mehr davon

> Sobald ein byte mit diesem Muster erkannt wird, wird
> dies als Vorspanntelegramm erkannt und die weiteren empfangen Bytes
> sollten von dem Empfangsinterrupt eigentlich ignoriert werden.
(wie schon mehrfach gesagt: macht alles keinen Sinn. Weder kann man 
einen Uart mit 0x55 Synchronisieren, noch sinnvoll ignorieren. Wenn der 
Uart 1 Byte verarbeiten kann, dann kann er auch 499 auf 0x55 abfragen 
und verwerfen)

> Dies passiert allerdings nicht so wie es sein sollte.
Wie sollte es denn sein? Ist da ein Code, der etwas verspricht? Oder 
eine Beschreibung, die Du umsetzen sollst und Dein Code macht nicht was 
er soll?


> was ich für meine Implementierung  auf der Mikrocontrollerseite beachten müsste 
damit die Kommunikation  erfolgreich funktioniert.

Was sind denn die Vorgaben an Dich?

von Peter D. (peda)


Lesenswert?

Ich würde zur Synchronisation eine Folge 0xC0, 0xFC im Wechsel senden 
und dann direkt vor den Daten ein 0xFE. Parity N oder O.

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


Lesenswert?

Peter D. schrieb:
> Mit Start und Stop-Bit ist das eine einzige 1-0-Folge, ohne jede Chance,
> eine verlorene Synchronisation zu beenden. Wer denkt sich denn bloß
> sowas aus.
So ein Bitmuster wird verwendet, um auf einer gleichspannungsfreien 
Übertragungsstrecke die Bezugspegel zu definieren und den Empfänger 
(samt seiner AGC oder Klemmschaltung) auf den Sender abzugleichen.

Bruno V. schrieb:
> War das mal Funk? 500 bytes machen bei einem Uart 0 Sinn.
Übliche gleichspannungsfreie Strecken (z.B. Ethernet) kommen mit einer 
wesentlich kürzeren Präambel mit nur wenigen Bytes aus.

Harald K. schrieb:
> Die Beschreibung lässt erahnen, daß das sendende Gerät eine Pause
> zwischen ihrem Datenschwall und dem Nutztelegramm macht.
Das wäre dann sehr sinnvoll. Da sollte mindestens 1 Byte Pause kommen.

: Bearbeitet durch Moderator
von Karl B. (gustav)


Lesenswert?

Ähhm, war da nicht mal was in grauer Vorzeit?
https://en.wikipedia.org/wiki/Software_flow_control

ciao
gustav

von Peter D. (peda)


Lesenswert?

Lothar M. schrieb:
> So ein Bitmuster wird verwendet, um auf einer gleichspannungsfreien
> Übertragungsstrecke die Bezugspegel zu definieren und den Empfänger
> (samt seiner AGC oder Klemmschaltung) auf den Sender abzugleichen.

Dafür hat sich ein modulierter Träger oder Manchester bewährt.

von Frank K. (fchk)


Lesenswert?

He S. schrieb:

> Ich weiß echt nicht mehr weiter, wie das ganze nun zum Laufen bringen
> kann.

Schau Dir funktionierende Implementationen an. IRDA SIR mit 115200 bps 
hat schon vor 30 Jahren funktioniert einwandfrei funktioniert. Dafür 
solltest Du genügend Beispiele im Netz finden. Und viele Mikrocontroller 
können IRDA SIR auch codieren und dekodieren, z.B. so ziemlich alle 
PIC24 und alle PIC32. Die Standards kannst Du Dir immer noch 
runterladen, und existierende Hardware sollte auch noch zu finden sein.

Ansonsten würde es für Deine Synchronisierung helfen, zwei Stopbits zu 
verwenden und/oder mindestens 3 Bitzeiten Pause zwischen zwei Bytes zu 
lassen. Du wirst sehen, dass die Synchronisation dann viel besser 
funktioniert und dass Du dann nicht unbedingt 500 Bytes brauchst. Und 
falls Du es nicht getan hast, solltest Du Framing Errors auch auswerten.

fchk

von Zo R. (hsch1978)


Lesenswert?

Danke euch bisher für die Untersützung.

Frank K.: Nur für den Vorspann sollten zwei Stopbits verwendet werden?
          Wenn ja, dann müsste ich am Bistmuster (0x55 0x55 ...) 
eigentlich
          nichts ändern.

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


Lesenswert?

Frank K. schrieb:
> Ansonsten würde es für Deine Synchronisierung helfen, zwei Stopbits zu
> verwenden und/oder mindestens 3 Bitzeiten Pause zwischen zwei Bytes zu
> lassen.
Das reicht nur aus, wenn man nach jedem low-Bit ein Stopbit erwartet. Es 
reicht aber nicht aus, wenn der 0x55 Datenstrom mit einem üblichen UART 
empfangen wird. Denn der könnte ja zufällig gerade erst wieder beim Bit 
0 gestartet sein, wenn tatsächlich aber das letzte Stopbit ankommt. Es 
müssen also 7 "Stopbits" kommen, damit das nächste Startbit sicher als 
Startbit erkannt wird.

Also: erst das Gezappel auf dem Bus (wenns schon sein muss), dann 1 Byte 
Ruhe und dann die Daten.

Peter D. schrieb:
> Lothar M. schrieb:
>> So ein Bitmuster wird verwendet, um auf einer gleichspannungsfreien
>> Übertragungsstrecke die Bezugspegel zu definieren und den Empfänger
>> (samt seiner AGC oder Klemmschaltung) auf den Sender abzugleichen.
> Dafür hat sich ein modulierter Träger oder Manchester bewährt.
Auch beim flankenorientierten Manchester wie es z.B. Ethernet verwendet, 
wird eine Präambel gesendet, damit sich der Phy auf die Pegel einregeln 
kann.

: Bearbeitet durch Moderator
von Zo R. (hsch1978)


Lesenswert?

Ok jetzt bin ich immer mehr verwirrt.

von Frank K. (fchk)


Lesenswert?

He S. schrieb:
> Danke euch bisher für die Untersützung.
>
> Frank K.: Nur für den Vorspann sollten zwei Stopbits verwendet werden?
>           Wenn ja, dann müsste ich am Bistmuster (0x55 0x55 ...)
> eigentlich
>           nichts ändern.

nein, immer. Wie andere schon gesagt haben, an besten eine Bytezeit 
Pause zwischen zwei Bytes machen. CRC am Ende, Bytelänge am Anfang.

fchk

von Zo R. (hsch1978)


Lesenswert?

ALso die UART auf zweit Stoppbits konfigurieren. Damit habe ich ja 
zwischen jedem Byte 1 Bit mehr.

von Zo R. (hsch1978)


Lesenswert?

Unser eigentliches Datenframe hat schon eine Bytelänge und auch CRC. Nur 
für den Vorspann, braucht man doch eigentlich keine Bytelänge und CRC.

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Lothar M. schrieb:
> Das reicht nur aus, wenn man nach jedem low-Bit ein Stopbit erwartet. Es
> reicht aber nicht aus, wenn der 0x55 Datenstrom mit einem üblichen UART
> empfangen wird. Denn der könnte ja zufällig gerade erst wieder beim Bit
> 0 gestartet sein, wenn tatsächlich aber das letzte Stopbit ankommt. Es
> müssen also 7 "Stopbits" kommen, damit das nächste Startbit sicher als
> Startbit erkannt wird.

eine definierte Pause ist in vielen Treibern schwieriger als ein back to 
back Datenstrom (ohne back-to-back garantiert ist was 
gleichspannungsfreies eh nicht möglich).

0x55 verwendet man ja eigentlich nur, wenn man eine PLL oder sowas 
einschwingen lassen will. Zur Start-Synchronisation ist alles besser 
(und ausreichend gut) geeignet, was die letzten Bits (also 
höchstwertigen) inclusive Parity 1 hat. 0xfd z.B.

Beitrag #7499795 wurde vom Autor gelöscht.
von Zo R. (hsch1978)


Lesenswert?

Bruno V. schrieb:

> eine definierte Pause ist in vielen Treibern schwieriger als ein back to
> back Datenstrom (ohne back-to-back garantiert ist was
> gleichspannungsfreies eh nicht möglich).
>
> 0x55 verwendet man ja eigentlich nur, wenn man eine PLL oder sowas
> einschwingen lassen will. Zur Start-Synchronisation ist alles besser
> (und ausreichend gut) geeignet, was die letzten Bits (also
> höchstwertigen) inclusive Parity 1 hat. 0xfd z.B.
Kann dich nicht verstehen.

von Christoph S. (mr9000)


Lesenswert?

Ist denn garantiert, dass das erste Byte im Datenstrom nicht 0x55 ist? 
;-)

von Zo R. (hsch1978)


Lesenswert?

Christoph S. schrieb:
> Ist denn garantiert, dass das erste Byte im Datenstrom nicht 0x55 ist?
> ;-)

Das erste empfangene Datenbyte ist leider nicht immer 0x55.
Manchmal 0xaa oder 0x95.

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


Lesenswert?

He S. schrieb im Beitrag #7499795:
> Hä verstehe deine Aussage nicht.
Halb so wild, es geht um Details. Und bei einer sereillen Schnitte muss 
man eben zwingend 1 komplettes Wartebyte (oder eben mindestens ein 0xFF) 
einschieben, wenn das Ding mal ausser Tritt gekommen ist. Und am 
einfachsten bekommt man es ausser Tritt, wenn man einen dauernden 
0-1-0-1-Bitstrom sendet.

He S. schrieb:
> Nur für den Vorspann, braucht man doch eigentlich keine Bytelänge und CRC.
Wozu ist dieser elend lange Vorspann überhaupt da? Warum verwendet ihr 
nicht einfach ein Manchester Encoding, wie andere optische Interfaces 
(z.B. Fernbedienungen) auch? Wenn du da allein zur Synchronisierung 500 
Bytes "vergeuden" kannst, kann die Übertragungsrate ja nicht so wichtig 
sein.

Bruno V. schrieb:
> (ohne back-to-back garantiert ist was
> gleichspannungsfreies eh nicht möglich).
RS232 ist per Definition nicht gleichspannungsfrei.

> 0x55 verwendet man ja eigentlich nur, wenn man eine PLL oder sowas
> einschwingen lassen will.
Wie gesagt: ich kenne das mit nachfolgender Klemmschaltung auch zum 
Entfernen eines DC-Offsets. Ich empfinde dieses "selbsterfundene" 
Übertragungsverfahren aber auch nicht als sonderlich schlau.

von Zo R. (hsch1978)


Lesenswert?

Nix Encoder. Ich habe die Hardware nicht selber entwickelt. Muss das so 
nehmen wie sie ist.

von Zo R. (hsch1978)


Lesenswert?

Der Vorspann ist da, damit der Controller erkennt oh jetzt ist ein 
Vorspann angekommen jetzt kann ich warten auf die richtigen Daten.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Christoph S. schrieb:
>> Ist denn garantiert, dass das erste Byte im Datenstrom nicht 0x55 ist?
>> ;-)
>
> Das erste empfangene Datenbyte ist leider nicht immer 0x55.
> Manchmal 0xaa oder 0x95.

Du hast den Witz nicht verstanden.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Nix Encoder. Ich habe die Hardware nicht selber entwickelt. Muss das so
> nehmen wie sie ist.

Dann sollte man mal einen Schaltplan zeigen. Zumindest einen, der auf 
die wesentlichen Dinge reduziert ist.

von Falk B. (falk)


Lesenswert?

Lothar M. schrieb:
> Wie gesagt: ich kenne das mit nachfolgender Klemmschaltung auch zum
> Entfernen eines DC-Offsets. Ich empfinde dieses "selbsterfundene"
> Übertragungsverfahren aber auch nicht als sonderlich schlau.

Das sind die allermeisten selbsterfundenen Dinge. Das Rad in 18937462ter 
Variation, mit beliebiger Anzahl Ecken ;-)

von Peter D. (peda)


Lesenswert?

He S. schrieb:
> Das erste empfangene Datenbyte ist leider nicht immer 0x55.
> Manchmal 0xaa oder 0x95.

Das wird ja immern verrückter. So wird das nichts.
Setzt euch mal an den Tisch und werdet Euch erstmal über das Protokoll 
einig.
Ein Protokoll ist einen eindeutige Regel, nach der Daten sicher 
ausgewertet und Fehler erkannt werden können. Und nicht irgendwas 
planlos Zusammengestückeltes.

von Adam P. (adamap)


Lesenswert?

He S. schrieb:
> Der Vorspann ist da, damit der Controller erkennt oh jetzt ist ein
> Vorspann angekommen jetzt kann ich warten auf die richtigen Daten.

He S. schrieb:
> Unser eigentliches Datenframe hat schon eine Bytelänge und auch CRC.

Also irgendwie finde ich das alles etwas zu viel des guten.

Also dein Controller soll auf das 0x55 Frame reagieren um dann zu wissen 
das irgendwann mal Daten kommen.
Ja, aber wenn er in der Lage ist das 0x55 Frame zu erkennen, dann sende 
doch gleich direkt dein Datenframe.

Spar dir doch einfach das ganze drum herum.
Da dein Datenframe ja eh CRC gesichert ist, wirst du ja schon erkennen 
ob das was angekommen ist nun richtig oder falsch ist.
Und da ja in deinem 0x55 Frame ja auch mal 0xAA oder was auch immer 
kommen kann, ist das nicht wirklich ein Sicherheitsfeature und in meinen 
Augen überflüssig.

Oder ist der Datenversand fix und du musst jetzt lediglich den 
Empfangsteil implementieren? Falls nicht, mach es anders ;)

von Karl B. (gustav)


Lesenswert?

Peter D. schrieb:
> das Protokoll

Yep, wenigstens einer, der mich versteht.
Xon X off ist das jetzt ein Protokoll oder nicht?
Und steinalt.
Beitrag "Re: UART RX Interrupt"
ciao
gustav

von Zo R. (hsch1978)


Lesenswert?

Jetzt nochmal zurück zum Anfang.

Meine Untersuchung hat gezeigt, dass sehr oft das erste empfangene Byte 
falsch ist. Ohne optische Kommunikation hat das empfangen von kurzen 
Telegrammern einwandfrei funktioniert. Dass das erste byte durch die 
optische Kommunikation ab und zu nicht korrekt empfangen wird, kann aber 
nicht durch den EInsatz eines UARt DMA gelöst werden oder? Das liegt 
schon an der Physik warum ab und zu die bytes nicht korrekt ankommen.

von Peter D. (peda)


Lesenswert?

He S. schrieb:
> Meine Untersuchung hat gezeigt, dass sehr oft das erste empfangene Byte
> falsch ist. Ohne optische Kommunikation hat das empfangen von kurzen
> Telegrammern einwandfrei funktioniert.

Dazu müßte man mal die komplette Schaltung der optischen Strecke sehen, 
insbesondere die Empfängerseite.
Ist das ein Lichtleiter oder kann auch Fremdlicht einfallen?

He S. schrieb:
> Dass das erste byte durch die
> optische Kommunikation ab und zu nicht korrekt empfangen wird, kann aber
> nicht durch den EInsatz eines UARt DMA gelöst werden oder?

Das Startbit muß stimmen, sonst hat die HW-UART verloren. Daher hat man 
bei Lichtübertragung typisch ein Protokoll mit Synchronisation auf 
Bitebene und nicht erst auf Bytes.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Meine Untersuchung hat gezeigt, dass sehr oft das erste empfangene Byte
> falsch ist. Ohne optische Kommunikation hat das empfangen von kurzen
> Telegrammern einwandfrei funktioniert.

Früher war alles besser.

> Dass das erste byte durch die
> optische Kommunikation ab und zu nicht korrekt empfangen wird, kann aber
> nicht durch den EInsatz eines UARt DMA gelöst werden oder?

;-) Du bis naiv.

> Das liegt
> schon an der Physik warum ab und zu die bytes nicht korrekt ankommen.

RICHTIG! Und du hast nicht den Hauch eines Schimmers, wo da die 
spezifischen Probleme liegen und wie man sie löst! Deshalb ist deine 
beste und fast einzige Chance, auf eine bewährte Standardlösung 
zurückzugreifen. Also Irda oder was ähnliches!

von Zo R. (hsch1978)


Lesenswert?

Für die optische KOmmunikation nutzten wir ein Optokopf.
Das mit der Synchronisation auf Bitebene wäre wohl der richtige Ansatz.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Für die optische KOmmunikation nutzten wir ein Optokopf.

Jaja, bloß nicht genauere Informationen geben. So wird das was! ;-)

von Uwe D. (monkye)


Lesenswert?

Sorry, das vielleicht das erste Byte nicht empfangen wird mag ja sein. 
Aber 500 ist einfach übertrieben. Was hindert Dich daran, als Vorspann 
z.B. 3x „IRdA“ zu senden, jeweils mit einer Pause von 1 Byte.
Wenn Deine Empfangsroutine das zwei Mal „IRdA“ erkannt hat, ist alles 
danach Nutzdaten. *)

Selbst im 433MHz Bereich brauche ich nicht mehr als 10 Zeichen für eine 
Synchronisation. Und da würde ich es verstehen, wenn ein 1€-Empfänger 
verwendet wird (der schlimmer rauscht als alle Meere dieser Welt).

Nachtrag:
*) Sofern nicht zufällig sogar 3x „IRdA“ empfangen wurde. Aber Du kennst 
ja die magischen Zeichen…

: Bearbeitet durch User
von Zo R. (hsch1978)


Lesenswert?

Wie sieht so eine Präamble bei IRDA aus? Ist eine DMA wirklich zwingend 
notwendig?

von Peter D. (peda)


Lesenswert?

He S. schrieb:
> Für die optische KOmmunikation nutzten wir ein Optokopf.

???
Also willst Du nun einen Stromzähler auslesen.

von Zo R. (hsch1978)


Lesenswert?

Kein Stromzähler. Es ist ein Projekt wo das Gerät einige Jahre 
stromsparend arbeiten muss. Deshalb dier Vorspann damit die UART durch 
die Photodiode nicht ständig ausgelöst wird.

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


Lesenswert?

He S. schrieb:
> Wie sieht so eine Präamble bei IRDA aus?
Falsches Textfenster. Probiers mal so:
- 
https://www.google.com/search?q=Wie+sieht+eine+Pr%C3%A4amble+bei+%22IRDA%22+aus

Und nimm einen der ersten Links...

> Ist eine DMA wirklich zwingend notwendig?
Nein. Prinzipiell muss die Übertragung sogar ohne DMA funktionieren. 
Die DMA ist nur dann sinnvoll, wenn ein kontiniuerlicher Datenstrom 
automatisiert abgehandelt werden kann. Und sie ist nur dann nötig, 
wenn wenn ein kontiniuerlicher Datenstrom automatisiert abgehandelt 
werden muss und die software per Interrupt oder Polling nicht schnell 
genug ist.

He S. schrieb:
> Deshalb dier Vorspann damit die UART durch die Photodiode nicht ständig
> ausgelöst wird.
Das ist noch nicht fertig gedacht und wird so nicht funktionieren, denn: 
wer soll diesen "Aufweck-Datenstrom" auswerten, wenn nicht der µC mit 
seiner UART?

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

He S. schrieb:
> Deshalb dier Vorspann damit die UART durch
> die Photodiode nicht ständig ausgelöst wird.

Die UART triggert auf jedes Startbit. D.h. der Vorspann spart keinen 
Strom, sondern kostet zusätzlich. Wenn Du das verhindern willst, mußt Du 
eine Trickschaltung davor setzen, die ihn ausfiltert. Oder ihn gar nicht 
erst senden.

von Uwe D. (monkye)


Lesenswert?

Peter D. schrieb:
> He S. schrieb:
>> Deshalb dier Vorspann damit die UART durch
>> die Photodiode nicht ständig ausgelöst wird.
>
> Die UART triggert auf jedes Startbit. D.h. der Vorspann spart keinen
> Strom, sondern kostet zusätzlich. Wenn Du das verhindern willst, mußt Du
> eine Trickschaltung davor setzen, die ihn ausfiltert. Oder ihn gar nicht
> erst senden.

Ein längerer Synchronimpuls, der sonst nicht vorkommt - nur müsstest Du 
ja dann wieder Hardware „davor basteln“. Vermutlich hast Du ja eine 
Grundmodulation auf dem IR-Signal, damit nicht jede Reflexion die 
Hardware auf Trab hält.
Falls Du ohne z.B. 38kHz Träger arbeitest, dann wundern mich die 500 
Byte „Präambel“ nicht…

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Wie sieht so eine Präamble bei IRDA aus? Ist eine DMA wirklich zwingend
> notwendig?

Weißt du überhaupt, was DMA ist oder plapperst du nur was nach? 
Nein, DMA löst dein Problem keine Sekunde.

von Εrnst B. (ernst)


Lesenswert?

Kann es sein, dass die originale Empfänger-Schaltung, die ihr da 
nachbauen wollt, den "0x55"(oder "0xAA")-Vorspann garnicht per UART/µC 
ausgewertet hat, sondern aus der Bitgewackel-Frequenz (0b1010101....) 
einfach analog und stromsparend ein Wake-Up-Signal für den µC gewonnen 
hat?
Würde auch erklären, warum der Vorspann mit 500 Bytes so irre lang 
ist... muss ja nach der Analogen Frequenzerkennung noch reichen bis der 
Empfänger-µC "gebootet" ist...

von Uwe D. (monkye)


Lesenswert?

Εrnst B. schrieb:
> Kann es sein, dass die originale Empfänger-Schaltung, die ihr da
> …
> Würde auch erklären, warum der Vorspann mit 500 Bytes so irre lang
> ist... muss ja nach der Analogen Frequenzerkennung noch reichen bis der
> Empfänger-µC "gebootet" ist...

Die gängigen 433MHz Handsender für Funksteckdosen wiederholen mehrfach 
ihre paar Bits. Und Gängige Billig-Funkthermometer verwenden häufig ein 
Synchronimpuls. Da wird aber nie und nimmer 500x ein Byte gesendet…

Wenn es unbedingt ein Standard-UART sein muss, dann reichen wenige Bytes 
zum synchronisieren. Keine Ahnung wo das Problem ist.
Der MC kann ja schlafen bis das erste Bit anklopft.

von Frank K. (fchk)


Lesenswert?

He S. schrieb:
> Wie sieht so eine Präamble bei IRDA aus? Ist eine DMA wirklich zwingend
> notwendig?

Lies das:

https://www.vishay.com/docs/82513/physicallayer.pdf
https://einstein.informatik.uni-oldenburg.de/rechnernetze/stichworte149.htm

DMA ist dafür unerheblich.

fchk

von Frank K. (fchk)


Lesenswert?

So, und nochmal eine Idee:

Das allgemeine Problem bei Infrarot-Übertragung ist die Störfestigkeit, 
durch Fremdlicht und auch durch Tageslicht.

Ich gehe mal jetzt mal davon aus, dass die zu übertragenden Datenmengen 
eher gering sind.

Eine Möglichkeit, die vor allem von Infrarot-Fernbedienungen genutzt 
wird, ist die Modulation des Signals mit einer Trägerfrequenz von 
irgendwas zwischen 28 und 56 kHz. Der Empfänger reagiert dann nur auf 
Licht, das mit genau dieser Frequenz moduliert ist. Damit kann 
Sonnenlicht den Receiver nicht mehr triggern.

Durch die Modulation ist natürlich die Datenrate begrenzt, denn in einer 
Bitzeit müssen ja etliche Taktzyklen der Modulationsfrequenz reinpassen, 
damit der Empfänger das Bit erkennt.

Wenn Du einen Empfänger mit einer Modulationsfrequenz von 57.6kHz 
verwendest, kommst Du gerade so auf maximal 9600 bps.

https://www.vishay.com/en/product/82667/

https://www.vishay.com/docs/80071/dataform.pdf

https://www.vishay.com/docs/82667/tsdp341.pdf

fchk

von Bruno V. (bruno_v)


Lesenswert?

He S. schrieb:
> Meine Untersuchung hat gezeigt, dass sehr oft das erste empfangene Byte
> falsch ist.

He, viele hier waren in Deinen Schuhen: Uart, aufwecken aus Tiefschlaf, 
Protokolle mit Präambel, Startkennung und/oder Pausen, Synchronisieren @ 
Back-to-Back, Übertragung per Licht, Funk, Irda, ..., 
Gleichspannungsfrei, CRC, ...

Wenn Du bei 0x55 sagst "das erste empfangene Byte ist oft falsch", dann 
weiß jeder, der das Mal am Oszi gesehen hat: Klar. Und kann Dir Ursache 
und Abhilfe benennen.

Du scheinst zu wenig Erfahrung zu haben um die Hinweise hier zu 
verstehen. Auch nicht, dass wir Dir nur dann Wochen an Erfahrung 
ersparen können, wenn Du Details zu Deinem Protokoll nennst.

Ich habe bisher verstanden: Die Gegenstelle sendet

 * als Präambel 500 x 0x55 back to back
 * mit 115200(??) Baud, even Parity, 1 Stopp-Bit (also 01010101011, bzw. 
01010101011010101010110101010101101010101011...)
 * dann eine Pause von 100(??)ms
 * dann ein Telegramm mit Startbyte 0x3f(??) ....

Fragen zur Präambel: Sie

 * weckt Deinen uC erst auf?
 * dient HW ohne µC (früher oder zum Aufwecken) oder der 
Frequenzerkennung, oder oder ? (Wer hat sich die und warum ausgedacht?)
 * kann durch Euch nicht geändert werden um besser in den Datenstrom zu 
synchronisieren?
 * ist nur zum Aufwecken und kann auf µC-Ebene verworfen werden, bis das 
"Startzeichen" kommt?

Wenn die Präambel Dich erst aufweckt, dann kannst Du sie auch getrost 
ignorieren und must nur sicher sein, dass das "Start-Byte" nicht durch 
Verschiebung in der Präambel steckt. Dein Interrupt-Code sieht dann z.B. 
so aus:
1
#define START_CHARACTER 0x3f
2
interrupt rx(void)
3
{
4
static int start;
5
unsigned char c = _uart_rx_fifo; /* das empfangene Byte lesen, Fehlerbehandlung spare ich mir */
6
7
   if(!start)
8
   {
9
      if(c==START_CHARACTER) {start = 1;}
10
      return;
11
   }
12
   ... /* verarbeite alle weiteren Protokolldaten */
13
   if(..) {start = 0;} /* irgendwann ist das Telegramm fertig */
14
}

von Zo R. (hsch1978)


Lesenswert?

Der IO Pin schaltet die Empfängerschaltung mit Empfangsdiode so, dass 
Daten von UART empfangen werden können. Dies passiert in einem sehr 
kurzen Zeitfenster. In diesem Fenster wird dann gewartet bis der 
Vorpsann empfangen wird. Sobald ein byte von der UART empfangen wird, 
wird der COntroller aufgeweckt und es kann der ganze Vorspann empfangen 
werden.

: Bearbeitet durch User
von Christoph S. (mr9000)


Lesenswert?

Das stellt mehr Fragen, als dass es Antworten bietet. Was für ein Pin 
denn auf einmal?

von Zo R. (hsch1978)


Lesenswert?

Es ist ein GPIO Pin der wird vom Controller auf 0V gesetzt. Damit wird 
eine externe Schaltung mit der Empfangsdiode gesteuert. Wenn 0V anliegen 
kann die Empfangsdiode Daten entgegenehmen (empfangen).

von Max M. (Gast)


Lesenswert?

Also ChatGPT sagt dazu :-)

Um sicherzustellen, dass die Kommunikation mit dem ARM Cortex M33 
Mikrocontroller erfolgreich funktioniert, müssen einige Dinge beachtet 
werden. Hier sind einige Punkte, die du bei der Implementierung auf der 
Mikrocontrollerseite berücksichtigen solltest:

UART-Konfiguration: Stelle sicher, dass die UART-Kommunikation 
ordnungsgemäß konfiguriert ist. Dies umfasst die richtige Baudrate, 
Datenbitlänge, Paritätsbit und Stopbit-Einstellungen. Überprüfe die 
Spezifikationen des optischen UART-Moduls, um sicherzustellen, dass die 
Konfiguration korrekt ist.

Interrupt-Handling: Implementiere einen Interrupt-Handler für den 
Empfang von Daten über die UART-Schnittstelle. Überprüfe den 
Interrupt-Status, um zu erkennen, ob ein Byte empfangen wurde.

Vorspanntelegramm-Erkennung: Überprüfe jedes empfangene Byte auf das 
Vorspanntelegramm-Muster (0x55). Wenn ein Byte mit diesem Muster erkannt 
wird, deaktiviere den Empfangsinterrupt, um sicherzustellen, dass die 
weiteren empfangenen Bytes ignoriert werden.

Warten auf das eigentliche Telegramm: Nachdem das Vorspanntelegramm 
erkannt wurde, musst du auf das eigentliche Telegramm warten, das vom 
Mikrocontroller empfangen werden soll. Hier kannst du eine Schleife oder 
eine Timer-Überwachung verwenden, um auf den Empfang des Telegramms zu 
warten.

Fehlerbehandlung: Implementiere eine geeignete Fehlerbehandlung, um 
sicherzustellen, dass die Kommunikation robust ist. Dies kann das 
Überprüfen auf Überlaufbedingungen, Prüfsummenberechnung oder andere 
Integritätsprüfungen beinhalten, um sicherzustellen, dass die 
empfangenen Daten korrekt sind.

von Falk B. (falk)


Lesenswert?

He S. schrieb:
> Es ist ein GPIO Pin der wird vom Controller auf 0V gesetzt. Damit wird
> eine externe Schaltung mit der Empfangsdiode gesteuert. Wenn 0V anliegen
> kann die Empfangsdiode Daten entgegenehmen (empfangen).

So wenig wie eine Schwalbe einen Sommer macht, so wenig macht ein 
Photodiode allein einen optischen Empfänger. Denn wir immer noch nicht 
kennen.

von Falk B. (falk)


Lesenswert?

Max M. schrieb:
> Also ChatGPT sagt dazu :-)

OMG! Ein Papagei könnte es nicht schlechter! Apfelmus ist Mus aus 
Äpfeln.

von Bruno V. (bruno_v)


Lesenswert?

He S. schrieb:
> Der IO Pin [vom Controller] schaltet die Empfängerschaltung mit Empfangsdiode 
so, dass Daten von UART empfangen werden können.

Mit "Controller" meinst Du den Empfangs-µC, mit "UART" dessen 
(internen/externen) UART, OK?


> Dies passiert in einem sehr  kurzen Zeitfenster.
Warum redest Du immer um den heißen Brei herum? Schreib doch: "für 10s" 
oder "100ms".

> In diesem Fenster wird dann gewartet bis der Vorspann empfangen wird.

und im nächsten Satz ist entweder alles "komisch" oder über den Haufen 
geworfen.

> Sobald ein byte von der UART empfangen wird, wird der COntroller aufgeweckt und 
es kann der ganze Vorspann empfangen werden.
?????
Der Controller war doch schon wach, er hat den IO-Pin gesetzt. Oder ist 
das ein Timermodul im uC, der das tut?

Der Uart ist extern? wie "weckt" er den µC? Wenn der Uart einfach die 
RX-Interrupt-Routine aufruft, dann kannst Du doch einfach den Code oben 
verwenden. Oder gibt es da noch externe HW, die irgendwas tut? Hast Du 
keinen Schaltplan oder ein Blockschaltbild von Deinem Aufbau? Hast Du 
die Schaltung selber gemacht oder von jemandem? Oder ein Foto, ein Link, 
irgendwas?

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.