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
staticvolatileuint8_t*DmxTx;
4
5
....
6
}elseif(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.
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
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
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
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
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.
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, ...