Forum: Compiler & IDEs UART Receive ohne dass Prozessor blockiert ist?


von Martial (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

meine UART läuft inzwischen einigermassen, doch die von mir verwendete
Receive Funktion wartet immer bis Daten ankommen.
Wenn ich eine serielle Verbindung haben möchte, bei welcher der
Prozessor auf gewisse Anfragen entsprechend antwortet, ist es ziemlich
ungünstig wenn er immer in dieser "while(!(UCSRA & (1<<RXC)))" hängen
bleibt.

Gibt es irgend eine Möglichkeit diese Receive Funktion anders zu
gestalten? Ich habe schon versucht, die while Schleife durch ein if zu
ersetzen. Doch dann werden die Daten nicht mehr korrekt empfangen...

Meine Routine für den ATMEGA32 ist im file uart.c angehängt.

Besten Dank und Gruss Martial

von OldBug (Gast)


Lesenswert?

Ja, mach es Interrupt driven.

Entsprechende Bits in den USART-Registern setzen und einen
Interrupthandler (SIGNAL(SIG_UART_RECEIVE) o.ä.) dafür schreiben. Nach
Empfangenem Zeichen entweder ein Flag setzen, welches in der
"main-loop" ausgewertet wird, oder in einen Ringbuffer schreiben und
in der "main-loop" regelmäßig nachschauen, ob etwas im Ringbuffer
steht.

von Martial (Gast)


Angehängte Dateien:

Lesenswert?

... ich hab das jetzt mal mit dem Interrupt versucht. Doch leider
klappts noch nicht ganz.
Solange ich über der IF Bedingung eine forever Schleife habe,
funktionierts. Der Interrupt setzt ein flag, welches dort überprüft
wird. Doch wenn ich die forever Schleife wegnehme (und nur noch die
forever Schleife des mains vorhanden ist), geht gar nichts mehr.
Natürlich dauert es dann viel länger bis er wieder an dieser IF
Bedingung vorbeikommt, ist das ein Problem?

Ich habe auch mal versucht das "temp = UDR" und
"USART_Transmit(temp)" direkt in den Interrupthandler zu nehmen, doch
auch das funktioniert nicht.

Gruss Martial

von mthomas (Gast)


Lesenswert?

Wird so eher nichts, doch ein "wenig zu einfach". Als "Inspiration"
vielleicht mal P. Fleurys uart-lib, die UART-Komponente aus der Procyon
AVRLIB oder diverse Libraries fuer UART in avrfreaks.net/user-projects
ansehen.
So die Hauptschleife "schnell ist", kann man auch einfach statt der
warte-while-Schleife fuer "RXC" ein "if" einbauen
(="Data-Avail.?") und nur dann wenn Daten anliegen den UDR auslesen
und verarbeiten.

von Marcus M. (Gast)


Lesenswert?

Hallo Martial,

schau Dir mal das hier an - als Inspiration - :

http://www.mikrocontroller.net/attachment.php/115750/uartporb.c

Gruß Marcus

von Martial (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe mir die Beispiele mal angeschaut und mir daraus ein Stück
eigenen Code zusammengebastelt.
Es soll ein ganzer String empfangen und dann mit dem String "test"
verglichen werden. Falls der Vergleich true ist, soll "test ok"
zurückgesendet werden.
Ein Teil davon funktioniert auch. Der Interrupt wird ausgelöst, aber
dann wird statt einem ganzen String nur immer das erste Zeichen
empfangen. D.h. für Einzeichen-strings funktioniert der Code, nicht
aber für richtige Strings.
Er scheint also nach einem Zeichen schon wieder aus der while- Schleife
herauszufallen... Aber im Beispiel fon Marcus wird das ja eigentlich
genau gleich gemacht, oder???


Besten Dank und Gruss Martial

P.S.: Code ist im uart_interrupt.c angehängt

von OldBug (Gast)


Lesenswert?

Kurz überflogen: das uart_recv-Flag muss in die if-abfrage auf 0x0d
0x0a.
Da muss das Flag gesetzt werden, weil erst dann der String vollständig
ist...

Habs aber nur überflogen...

von Martial (Gast)


Angehängte Dateien:

Lesenswert?

... ja da hast Du natürlich recht! Und das Ganze kann auch nur
funktionieren wenn ich mit "test\r\n" vergleiche. Aber es wird
immer noch nur ein Zeichen empfangen...

von Martial (Gast)


Angehängte Dateien:

Lesenswert?

Ich habs! Nach etlichen Versuchen läuft mein UART endlich mit Interrupt!
Es sind gleich zwei Versionen entstanden, wobei die erste die schönere
ist. Die zweite bleibt hängen, wenn kein CR/LF empfangen wird!
Für die Nachwelt habe ich meine Lösung mal angehängt...


Gruss Martial

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.