Forum: Mikrocontroller und Digitale Elektronik UART ISR Reihenfolge


von Karsten K. (karsten42)


Lesenswert?

Moin Moin,

ich habe im Forum gesucht, und das Datenblatt gelesen.
ATMEGA1284P @ 20Mhz

Ich habe ein Problem mit der Reihenfolge von UART ISR USART0_UDRE_vect 
und USART0_TX_vect. Wird nach dem durchlaufen der ISR UDRE und dessen 
Abschaltung die ISR TX aufgerufen? Und warum eigentlich??

Init:
1
UBRR0H = 0;
2
UBRR0L = 4; //250kbaud
3
UCSR0C |= (3 << UCSZ00) | (1 << USBS0); // 8Bit , 2 Stop Bit
4
5
UCSR0B |= (1 << TXEN0) | (1 << TXCIE0) | (1 << UDRIE0);
6
UDR0 = 0; // start USART

Transfer enabled sowie ISR für "transfer complete(TX)" und "data 
register empty (UDRE)". Im Forum habe ich gelesen, das zunächst die ISR 
UDRE aufgerufen wird, da UDR0 ja 0 ist.
1
ISR( USART0_UDRE_vect ) {
2
   
3
   static volatile uint8_t *DmxTx;
4
5
....
6
  } else if (gDmxStateA == txRESET) {
7
8
     UCSR0B &= ~(1 << UDRIE0); //UDRE ISR off
9
     DmxTx = DmxTxA; // reset txpointer to first byte of transfer array
10
11
  } else {
12
13
     UCSR0B &= ~(1 << UDRIE0);
14
  }
15
}

Beim ersten Aufruf wäre gstate auf INITIAL gesetzt. Somit wird die ISR 
UDRE abgeschaltet undder transferpointer auf ein daten array gesetzt.
1
ISR( USART0_TX_vect ) {
2
3
if (DmxState == txRESET) {
4
5
   UCSR0B &= ~(UDRIE0);
6
   PORTD &= ~(1 << PD1);    //reset
7
   OCR0A = TCNT0 + 39;  //typ. 125µS
8
   gDmxStateA = txMAR;
9
10
} else if {
11
....
12
13
14
}

von Achim M. (minifloat)


Lesenswert?

Karsten K. schrieb:
> das zunächst die ISR
> UDRE aufgerufen wird, da UDR0 ja 0 ist.

UDR ist in gewisser Hinsicht ein geteiltes Register. Schreiben und Lesen 
gehen zwar auf dieselbe Adresse, aber landen tatsächlich auf zwei 
verschiedenen Ressourcen. Schreiben adressiert den TX-Teil, Lesen den 
RX-Teil.

Außerdem heißt "USART Data Register Empty" nicht zwingend, dass da eine 
0x00 drin steht. Das ist vielmehr ein Signal bzw. Flag, welches aus der 
Sendehardware generiert wird. Das passiert genau dann, wenn die Daten 
vom TX-Teil aus dem UDR, auf das gerade geschrieben wurde, 
abgeholt/weiter gepuffert worden ist.

Der TX-Vektor wird angesprungen, wenn er mit dem Senden fertig ist, der 
UDRE-Vektor, wenn das Register durch die Pufferung(das geht intern mit 
D-Flipflops) fürs Senden kopiert worden ist.

Warum nimmst du nicht nur einen Interrupt und definierst dir ein Flag, 
das markiert, ob dein Lesevorgang aus dem Daten-Array schon erfolgt ist? 
Warum nimmst du nicht gleich nur den UDRE-Vektor, schneller Senden wirst 
du durch beide Interrupt-Routinen auch nicht können...
Es dauert ja eine gewisse Zeit, bis der Kram mit 57,6kBaud rausgeschoben 
ist.

mfg mf

von spess53 (Gast)


Lesenswert?

Hi

>Wird nach dem durchlaufen der ISR UDRE und dessen
>Abschaltung die ISR TX aufgerufen? Und warum eigentlich??

Ist das die Frage zu deinem Beitrag?

Der UDR-Flag wird gesetzt, wenn der Transmitpuffer ein Byte aufnehmen 
kann.

Das TX-Flag wird gesetzt, wenn ein Byte übertragen wurde und kein Byte 
mehr im Puffer vorhanden ist.

Daraus folgt, das das UDR-Flag vor dem TXC-Flag gesetzt wird und bei 
freigegbenen INterrupts diese ausgelöst werden.

MfG Spess

von Karsten K. (karsten42)


Lesenswert?

Hallo mf,

Daaanke für die ausführliche nette Antwort. UDR0 wird ja im init teil 
des codes auf 0 gesetzt, also beschrieben. Das löst dann wohl den 
Interrupt für den UDRE-vector aus. Das wäre mir soweit klar.
Genau wie du beschrieben hast, wird der TX-vector aufgerufen wenn das 
senden der Daten fertig ist.
Es ist nicht mein Code und ich versuche diesen "nur" zu verstehen weil 
eben nicht das passiert was ich erwate...:-( Die Frage ist jedoch nicht 
ganz geklärt:
Wird der interrupt TX-vector aufgerufen nachdem UDRE-vec durchlaufen 
wurde?
UDR0=0 löst auf jeden Fall den UDRE-Vec aus ( laut Forum ). Es wird aber 
nichts versendet, da der Inhalt von UDR0 eben "nichts" enthält. Es sei 
denn auch "nichts" wäre etwas was gesendet wird, dann wäre ein Aufruf 
vin TX-vec logisch...
ich bin etwas verwirrt... :-)



Gruß
Karsten

von spess53 (Gast)


Lesenswert?

Hi

>Wird der interrupt TX-vector aufgerufen nachdem UDRE-vec durchlaufen
>wurde?

Nicht zwangsläufig. Wenn du schnell genug Bytes nachschiebst nicht.

>UDR0=0 löst auf jeden Fall den UDRE-Vec aus ( laut Forum ). Es wird aber
>nichts versendet, da der Inhalt von UDR0 eben "nichts" enthält. Es sei
>denn auch "nichts" wäre etwas was gesendet wird, dann wäre ein Aufruf
>vin TX-vec logisch...

Null ist etwas und wird gesendet.

MfG Spess

von Stefan E. (sternst)


Lesenswert?

Karsten K. schrieb:
> Wird der interrupt TX-vector aufgerufen nachdem UDRE-vec durchlaufen
> wurde?

Es gibt keinen direkten Zusammenhang zwischen diesen beiden Interrupts. 
Der TX-Interrupt wird aufgerufen, wenn das Senden fertig. Wie das Senden 
vor eingeleitet wurde, ist dabei völlig irrelevant.

Karsten K. schrieb:
> UDR0=0 löst auf jeden Fall den UDRE-Vec aus ( laut Forum ). Es wird aber
> nichts versendet, da der Inhalt von UDR0 eben "nichts" enthält. Es sei
> denn auch "nichts" wäre etwas was gesendet wird, dann wäre ein Aufruf
> vin TX-vec logisch...

Du musst dich von der Vorstellung lösen, dass 0=leer. Der Interrupt löst 
aus, wenn in UDR Platz für neue Daten ist. Und UDR0=0; schreibt eine 
Null nach UDR und die wird dann auch gesendet. 0 ist nicht Nichts.

von Karsten K. (karsten42)


Lesenswert?

Ahhhh DAAANKE!!!

Die Welt ist wunderbar! Das Nichts ist existent und wird versendet.

Herzlichen dank für eure Mühe

Gruß
Karsten

von Karl H. (kbuchegg)


Lesenswert?

Karsten K. schrieb:
> Ahhhh DAAANKE!!!
>
> Die Welt ist wunderbar! Das Nichts ist existent und wird versendet.

Ein µC ist ein ganz wunderbare einfaches 'Wesen'.

Sein einziger Daseinszweck ist es, ständig den Zyklus auszuführen

    Befehl holen
    Befehl decodieren
    Befehl ausführen

Das macht er ständig. Genauso wie 0 nicht mit 'nichts' gleichzusetzen 
ist, ist es auch für einen µC nicht möglich, 'nichts' zu tun. Ein µC 
(wenn er Strom hat) macht immer irgendwas! Er lagert nicht die Beine 
hoch und tut nichts sondern durchläuft wieder und immer wieder diesen 
Zyklus: Befehl holen - Befehl deco....

So etwas wie 'Nichts' gibt es nicht in einem Computer. Wenn man das 
Konzept von 'Nichts' einführen will, dann ist der Programmierer 
gefordert einen bestimmten Wert per Definition als 'Nichts spezielles' 
zu vereinbaren und im Programm so zu behandeln. Dem µC an sich ist das 
aber wurscht. Den interessiert das nicht. Der ist glücklich mit Befehl 
holen, Befehl dekodieren, ...

von spess53 (Gast)


Lesenswert?

Hi

>Den interessiert das nicht. Der ist glücklich mit Befehl
>holen, Befehl dekodieren, ...

Manchmal schläft er aber auch.

MfG Spess

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.