Moin, ich möchte den Datenversandt per USART nun per ISR machen lassen. Dh ich schreibe vorher alle Daten in einen Sendepuffer und lasse dann die ISR diesen "abarbeiten" (im Prinzip analog zum Senden per ISR). Meine Frage ist jetzt, wie ich das ganze "anwerfe" sobald ich etwas zu senden habe. Kann ich dazu aus dem Program heraus einfach das USR->TXC Bit setzen, wird daruch der Interrupt ausgelöst? Wenn das nicht geht, wie macht man das dann? Beendet wird der sendevorgang dann dadurch, daß nach dem letzten Zeichen einfach nichts mehr ins UDR schreibe oder?
Nicht das TXCIE, sondern UDRIE. Letzteres kommt immer, wenn Platz für neue Sendedaten da ist, ersteres nur, wenn eine Sendung eines Bytes gerade abgeschlossen ist.
Nein, das Anwerfen musst Du selbst machen, der Interrupt kommt nur, wenn der Sendebuffer leer ist. Wenn alle Daten im Buffer sind, dann aktivierst Du den Interrupt und startest den 1. Transfer (UDR schreiben). Sobald der Atmega bereit ist, also UDR mit dem nächsten Zeichen beschrieben werden kann, löst er einen Interrupt aus. Die ISR nimmt nun das nächste Zeichen, schreibt UDR, fertig. Wenn der Atmega wieder bereit ist, kommt der nächste Interrupt usw. Wenn die ISR nichts mehr zum Schreiben hat, dann hört das ganze auf, eventuell kann die ISR die Interrupts deaktivieren.
> eventuell kann die ISR die Interrupts deaktivieren
Nicht nur eventuell.
Der UDRIE kommt immer solange das Senderegister leer ist und nicht nur
wenn das Senderegister leer wurde.
Deaktiviert man den Interrupt nicht, so kommt der andauernd sobald alles
abgearbeitet wurde.
Von daher muss man auch nicht das erste Zeichen ins UDR schreiben.
Buffer beschreiben und den Interrupt einschalten. Sobald die UDR Einheit
wieder was aufnehmen kann, kommt der erste Interrupt weil ja das
Senderegister leer ist.
UDRIE ist anders als der TXCIE
TXCIE zeigt ein Ereignis an (das Zeichen ist komplett draussen)
UDRIE zeigt einen Zustand an (das Senderegister ist leer)
Und konsequenterweise kommt der UDRIE daher auch, solange dieser Zustand
vorliegt.
Ok, dh zum "triggern" aktiviere ich das UDRIE, (das TXCIE bleibt immer aus?). Er merkt: "UDR I S T leer" daher wird die ISR routine aufgerufen. Wenn ich nicht das letzte Zeichen sende dann füttere ich den UDR ein letztes mal deaktiviere auch innerhalb der ISR den UDR-Interupt wieder. Weshalb dann nach dem senden, wenn der UDR wieder leer ist nichts mehr passiert. So richtig verstanden?
Phillip Hommel schrieb: > Ok, dh zum "triggern" aktiviere ich das UDRIE, (das TXCIE bleibt immer > aus?). > Er merkt: "UDR I S T leer" daher wird die ISR routine aufgerufen. Wenn > ich nicht das letzte Zeichen sende dann füttere ich den UDR ein letztes > mal deaktiviere auch innerhalb der ISR den UDR-Interupt wieder. Weshalb > dann nach dem senden, wenn der UDR wieder leer ist nichts mehr passiert. > So richtig verstanden? Klingt richtig. Du kannst dich von der Vorstellung leiten lassen, dass der UDRIE-ISR Aufruf die Rückfrage von der UART darstellt: "Hast du noch was für mich zu tun?" Und dementsprechend reagiert deine ISR darauf. Entweder sie füttert die UART über UDR mit neuen Daten, oder sie schaltet ab, wenn im Buffer nichts mehr vorliegt. Wenn du das geschickt machst, kannst du zb in einen genügend großen Buffer durchaus auch dann noch Zeichen einfügen, während die Abarbeitung des bereits im Buffer enthaltenen noch läuft. Von daher würde ich auch den Interrupt nicht unmittelbar nach dem Einstellen des letzten Zeichens ins UDR Register abdrehen, sondern erst dann wenn ein ISR Aufruf erfolgt und in der ISR festgestellt wird, dass nichts Versendbares vorhanden ist.
So, klappt soweit aus der ISR raus. Danke schonmal dafür. Zu Pufferwaltung habe ich auch schon einige Ideen, damit man wie Du schon sagtest bereits nachfüllen kann während hinten noch gesendet wird. Allerdings hänge ich an der Ausführung ein wenig. Ich erstelle bisher immer einen String variabler Länge (ist zwar meist in einem gewissen Bereich aber eben nicht fix) und sende dann diesen Puffer bis er an den Nullterminator kommt und sende stattdessen dann noch ein Linefeed '\n'. Jetzt schwimme ich ein wenig wie ich das managen soll mit mehreren Puffern. Eine Idee wäre, eine Art zweidimensionales Array benutze und dazu ein Prüfbyte in dem das jeweilige Bit immer gesetzt wird wenn die entsprechende Zeile einen neuen String zum senden übergeben bekommt. Wenn die ISR diesen gesendet hat wird das prüfbyte wieder gelöscht und der Pufferplatz ist wieder "frei". Die ISR schaut dann ob das byte ungleich null ist und sucht dann ggf bitweise weiter nach dem nächsten noch nicht gesendeten string... Klingt das für euch vernünftig oder wird das normalerweise anders gemacht. Kennt Ihr da ein paar Programmierbeispiele (am besten in C) wo man sich das eine oder andere abgucken könnte?
Phillip Hommel schrieb: > Jetzt schwimme ich ein wenig wie ich das managen soll mit mehreren > Puffern. Nicht mehrere Buffer. Ein Buffer, ausgeführt als Ringbuffer. Alle auszugebenden Texte landen dort drinnen. Die Ringbufferverwaltung benutzt nicht den Inhalt des Buffers, um festzustellen ob da etwas enthalten ist, sondern ihr Buchhaltungs-Variablen.
Die Ausgabe über die UART ist eigentlich ein Musterbeispiel für die Verwendung eines FiFos. Damit kann man zu beliebigen Zeitpunkten Daten schreiben (sofern noch Platz im FiFo ist), die dann nach und nach gesendet werden.
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.