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
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.
... 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
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.
Hallo Martial, schau Dir mal das hier an - als Inspiration - : http://www.mikrocontroller.net/attachment.php/115750/uartporb.c Gruß Marcus
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
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...
... 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...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.