Forum: Mikrocontroller und Digitale Elektronik Mehrere serielle Schnittstellen gleichzeitig verwenden


von Matthias F. (frank91)


Lesenswert?

Hallo alle miteiander :P

Ich habe einen Atmel xmega controller mit diesem ich 4 serielle 
Schnittstellen gleichzeitig verwende. Es werden sowohl Daten gesendet 
als auch Empfangen.

Bei 2 der Schnittstellen sende ich Daten zu unterschiedlichen 
Zeitpunkten und erwarte eine Antwort.
Bei den anderen 2 erwarte ich Daten zu unterschiedlichen Zeiten und 
sende anschließend sofort eine Antwort zurück.

An sich funktioniert auch alles. Wenn allerdings eine Schnittstelle 
gerade viel verwaltet kommt es ab und zu mal vor, dass eine andere nicht 
ganz richtig funktioniert.

Deshalb hier meine Frage. Wie verwalte ich mehrere Schnittstellen 
eigentlich Sinnvoll in der Software? Gibt es hier sowas wie eine 
Faustregel oder einen Grundaufbau den man befolgen sollte?

Bei einer der Schnittstellen sende ich vom Controller aus sofort eine 
Antwort noch in der Interruptroutine. Das Funktionert auch. Aber das 
könnte auch schon zu Überschneidungen führen, wenn eine andere 
Schnittstelle eigentlich gerade etwas senden wollte oder nicht?

Außerdem kann ich jedem Empfangsinterrupt eine Priorität geben. Macht es 
hier in irgendeinem Fall Sinn unterschiedliche Prioritäten zu vergeben?

ich hoffe, dass ich meine Frage verständlich formuliert habe :-/

von Uwe (de0508)


Lesenswert?

Hallo Matthias,

setze doch für alle Schnittstellen RX- und TX-FiFo mit jeweils 16-128 
Zeichen auf, so dass das Senden und Empfangen nur im Hintergrund 
stattfinden kann.

So bleibt das System schlank und reagiert auch promt auf weitere externe 
Ereignisse.

von Michael (Gast)


Lesenswert?

Matthias Frank schrieb:
> Bei einer der Schnittstellen sende ich vom Controller aus sofort eine
> Antwort noch in der Interruptroutine.

Und jetzt sag nicht, dass du in der Interruptroutine auch noch eine 
Warteschleife hast, die guckt, ob das Senderegister frei ist.

von Uwe (de0508)


Lesenswert?

Hallo,

wie so ein FiFo funktioniert, kannst Du bei Peter Dannegger (peda)

# Beitrag "AVR-GCC: UART mit FIFO"

und weiteren Artikel von ihm nachlesen.

von Falk B. (falk)


Lesenswert?

@Matthias Frank (frank91)

>An sich funktioniert auch alles. Wenn allerdings eine Schnittstelle
>gerade viel verwaltet kommt es ab und zu mal vor, dass eine andere nicht
>ganz richtig funktioniert.

Falsches Konzept.

>Deshalb hier meine Frage. Wie verwalte ich mehrere Schnittstellen
>eigentlich Sinnvoll in der Software? Gibt es hier sowas wie eine
>Faustregel oder einen Grundaufbau den man befolgen sollte?

Nichtblockierende Arbeitsweise, Interrupt, Multitasking und ggf. 
ein FIFO.

>Bei einer der Schnittstellen sende ich vom Controller aus sofort eine
>Antwort noch in der Interruptroutine.

AUA! SO NICHT! Siehe Interrupt.

> Das Funktionert auch.

Im einfachsten Fall, der sowieso keinen Interrupt braucht.

> Aber das
>könnte auch schon zu Überschneidungen führen, wenn eine andere
>Schnittstelle eigentlich gerade etwas senden wollte oder nicht?

EBEN!

>Außerdem kann ich jedem Empfangsinterrupt eine Priorität geben. Macht es
>hier in irgendeinem Fall Sinn unterschiedliche Prioritäten zu vergeben?

Kann man machen, löst aber dein Grundproblem nicht.

von Georg (Gast)


Lesenswert?

Matthias Frank schrieb:
> Bei einer der Schnittstellen sende ich vom Controller aus sofort eine
> Antwort noch in der Interruptroutine

Das kann man nur machen, wenn es unter keinen Umständen Zeit kostet, 
also Tx immer verfügbar ist.

Sonst ist es sinnvoll, für alle UARTs Rx- und Tx-Interrupts einzurichten 
und in den ISR nur das/die verfügbaren Bytes in einen FIFO-Ringspeicher 
zu stecken, bzw. das nächste Byte aus dem FIFO in Tx zu schreiben. 
Irgendwann mal kümmert sich dann dein Hauptprogramm darum, ob empfangene 
Messages verfügbar sind (das Senden geht ja "von allein" 
interruptgesteuert). Hast du Messages maximaler Länge, deren Ende 
gekennzeichnet ist z.B. durch CR, so brauchst du auch keine 
FIFO-Verwaltung, sondern kannst mit je 2 wechselweise benutzten 
Message-Speichern arbeiten, das ist etwas einfacher und übersichtlicher. 
Eine Reaktion ist erst erforderlich, wenn die ganze Message im Speicher 
steht.

Deine Mainloop besteht dann einfach aus "Was empfangen? Wenn Ja 
antworten" für jeden Kanal. Und natürlich Fehlerbehandlung.

Georg

von Matthias F. (frank91)


Lesenswert?

Sorry, dass ich jetzt erst antworte.

Ich habe das ganze jetzt so gelöst, wie ihr gesagt habt. In meiner 
Interruptroutine schreibe ich das empfangene in einen Puffer. In der 
Main werte ich diesen Puffer aus und sende Daten zurück.
Dies behob aber nicht meinen Fehler.

Den Fehler habe ich allerdings inzwischen gefunden. Ich hatte eine 
zweite Platine mit einem FT232RL Chip. Diese zweite Platine hatte ich 
allerdings nur ab und zu angeschlossen. Dann waren TX und RX wohl offen 
und es kam immer zu häufigen Interrupts. Zumindest denke ich das, da 
wenn der FT232RL angeschlossen ist alles funktioniert.

von Uwe (de0508)


Lesenswert?

Hallo Matthias,

genau, deshalb ist auch mein Tipp für Atmel AVR µC an den RXDn 
Datenleitungen den Pullup ein zu schalten.
Die TXDn Datenleitungen setzen ich als Ausgang und gebe ihnen einen 
Highpegel vor.

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.