Atmega32 TX per ISR "triggern"

OP #1495503
Lesenswert?

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?
#1495518
Lesenswert?

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.
#1495533
Lesenswert?

> 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.
OP #1495572
Lesenswert?

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?
#1495583
Lesenswert?

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.
OP #1495814
Lesenswert?

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?
#1495820
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren