Forum: Mikrocontroller und Digitale Elektronik ATmega 328p USART: wird TXC auch automatisch gelöscht?


von Uhu U. (uhu)


Lesenswert?

Das Datenblatt des 328 sagt:
1
• Bit 6 – TXCn: USART Transmit Complete
2
This flag bit is set when the entire frame in the Transmit Shift Register
3
has been shifted out and there are no new data currently present in the
4
transmit buffer (UDRn). The TXCn Flag bit is automatically cleared when
5
a transmit complete interrupt is executed, or it can be cleared by writing
6
a one to its bit location. The TXCn Flag can generate a Transmit Complete
7
interrupt (see description of the TXCIEn bit).

Wird TXCn auch automatisch rückgesetzt, wenn ein Zeichen ins 
Shiftregister geschoben wird, oder bleibt es einfach stehen, wenn es 
gesetzt war und keine Interrupts benutzt werden?

von Karl M. (Gast)


Lesenswert?

Hallo,

für mich liest sich das so, wie es bei allen anderen Interrupts auch 
ist.

Entweder per Software abfragen und löschen oder eine Interrupt Service 
Routine eintragen.

von Thomas E. (thomase)


Lesenswert?

Interrupt Flags werden nur automatisch gelöscht, wenn der dazugehörige 
Interrupt ausgeführt wird. Sonst bleiben sie bis in alle Ewigkeit 
stehen.

von c-hater (Gast)


Lesenswert?

Uhu U. schrieb:

> Das Datenblatt des 328 sagt:
>
1
> • Bit 6 – TXCn: USART Transmit Complete
2
> This flag bit is set when the entire frame in the Transmit Shift 
3
> Register
4
> has been shifted out and there are no new data currently present in the
5
> transmit buffer (UDRn). The TXCn Flag bit is automatically cleared when
6
> a transmit complete interrupt is executed, or it can be cleared by 
7
> writing
8
> a one to its bit location. The TXCn Flag can generate a Transmit 
9
> Complete
10
> interrupt (see description of the TXCIEn bit).
11
>
>
> Wird TXCn auch automatisch rückgesetzt, wenn ein Zeichen ins
> Shiftregister geschoben wird

Steht da oben irgendwas davon, dass das geschehen würde? Nein! Also: 
nein.

> oder bleibt es einfach stehen, wenn es
> gesetzt war und keine Interrupts benutzt werden?

Automatisch gelöscht wird das Flag nur dann, wenn du den TXC-Interrupt 
benutzt. Ansonsten nicht und du musst es ggf. manuell löschen.

Und komisch: genau das ist, was da oben in dem DB-Auszug steht. Was also 
soll die Frage? Steht doch alles schon da! No need to ask again.

von Uhu U. (uhu)


Lesenswert?

c-hater schrieb:
> Automatisch gelöscht wird das Flag nur dann, wenn du den TXC-Interrupt
> benutzt.

Genau das steht dort nicht.

von Karl M. (Gast)


Lesenswert?

Hallo,

c-hater gibt nur dass wieder, was ich auch ausgesagt habe.
Atmel beschreibt immer nur dass, was auch passiert. Interpretationen 
sind nur in außnahme Fällen möglich, und auf diese wird über eine 
Randnotiz hingewiesen.

Denke etwas weiter, bzgl. was nicht geschrieben steht, wenn alles 
eintreffen könnte, was nicht beschrieben wurde, dann müsste man noch 
nichts beschreiben - aha ?!

von Uhu U. (uhu)


Lesenswert?

Karl M. schrieb:
> Denke etwas weiter, bzgl. was nicht geschrieben steht, wenn alles
> eintreffen könnte, was nicht beschrieben wurde, dann müsste man noch
> nichts beschreiben - aha ?!

Andersrum wird ein Schuh draus: was nicht beschrieben ist, ist erst mal 
nicht definiert und man muss sich fragen, was in diesen Fällen passiert. 
Genau das habe ich getan.

von holger (Gast)


Lesenswert?

>Andersrum wird ein Schuh draus: was nicht beschrieben ist, ist erst mal
>nicht definiert und man muss sich fragen, was in diesen Fällen passiert.

Es ist doch alles beschrieben.

von Uhu U. (uhu)


Lesenswert?

Folgendes Problem:

Am USART hängt ein HC-05 Bluetooth Adapter, der durch Hochziehen des Pin 
34 in den AT-Mode versetzt werden soll.

Wenn der USART noch aktiv ist, wird mindestens das aktuell übertragene 
Zeichen nicht korrekt übertragen und der HC-05 kriegt gleich Müll zu 
fressen, was gleich zu komischen Effekten führt.

Wie kann man prüfen, ob der USART noch aktiv ist?

UDRE zu pollen hilft überhaupt nichts, denn das Shiftregister ist noch 
aktiv, wenn UDRE gesetz wird.
TXC zu pollen, funktioniert nur, wenn der UASART überhaupt aktiv ist, 
das ist also auch keine Lösung.

Man kann die Situation mit einem ausreichend langen Delay umschiffen.

Gibts auch eine kausale Lösung ohne Data Register Empty interrupt dafür?

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Uhu U. schrieb:
> c-hater schrieb:
>> Automatisch gelöscht wird das Flag nur dann, wenn du den TXC-Interrupt
>> benutzt.
>
> Genau das steht dort nicht.

 Genau das steht dort doch.

Uhu U. schrieb:
> Wie kann man prüfen, ob der USART noch aktiv ist?

 Wenn du ein Zeichen in UDR0 schreibst, wird der auch gesendet.
 Nachdem Stopbit raus ist, wird TXC gesetzt.
 Wenn aber in  der Zwischenzeit etwas in UDR0 geschrieben wird,
 wird der TXC erst nach diesem Byte gesetzt.

 USART ist nach setzen des TXC bits mit Sicherheit nicht aktiv.

von Uhu U. (uhu)


Lesenswert?

Marc V. schrieb:
> USART ist nach setzen des TXC bits mit Sicherheit nicht aktiv.

Wenn TXC nicht gesetzt ist, heißt das nicht, dass der USART aktiv ist...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Uhu U. schrieb:
> Marc V. schrieb:
>> USART ist nach setzen des TXC bits mit Sicherheit nicht aktiv.
>
> Wenn TXC nicht gesetzt ist, heißt das nicht, dass der USART aktiv ist...

 Hat das jemand behauptet ?

 Dein Program wird doch wissen, ob da etwas gesendet wurde oder nicht.

 Wenn ich senden will, dann prüfe ich zuerst ob UDRE0 gesetzt ist.
 Falls ja, geht es weiter.
 Insofern interessiert dich TXC beim reinschreiben überhaupt nicht.

 Erst beim letzten Zeichen kann das ev. von Interesse sein.

von Uhu U. (uhu)


Lesenswert?

Marc V. schrieb:
> Hat das jemand behauptet ?

Nein, aber das würde das oben skizzierte Problem lösen...

>  Dein Program wird doch wissen, ob da etwas gesendet wurde oder nicht.

Eine Bibliothek weiss das meistens nicht...

von Georg (Gast)


Lesenswert?

Uhu U. schrieb:
> was nicht beschrieben ist, ist erst mal
> nicht definiert und man muss sich fragen, was in diesen Fällen passiert

auch bei Vollmond oder beim Brexit?

Uhu U. schrieb:
> Genau das habe ich getan

Ja, du hast bloss Zillionen Ereignisse dabei vergessen, die auch 
passieren können.

Georg

von Thomas F. (igel)


Lesenswert?

Uhu U. schrieb:
> Wie kann man prüfen, ob der USART noch aktiv ist?

Steht doch eigentlich im Datenblatt zum USART Kapitel 24.7.1:
1
USART_Transmit:
2
; Wait for empty transmit buffer
3
in r17, UCSR0A
4
sbrs r17, UDRE
5
rjmp USART_Transmit
6
; Put data (r16) into buffer, sends the data
7
out UDR0,r16
8
ret

von Uhu U. (uhu)


Lesenswert?

Thomas F. schrieb:
> Steht doch eigentlich im Datenblatt zum USART Kapitel 24.7.1:

Du kennst den Unterschied zwischen dem transmit buffer und dem 
shiftregister?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Uhu U. schrieb:
> Du kennst den Unterschied zwischen dem transmit buffer und dem
> shiftregister?

 Ich kenne den Unterschied, warum ?

 Du kannst lesen ?
Marc V. schrieb:
> Dein Program wird doch wissen, ob da etwas gesendet wurde oder nicht.

> Insofern interessiert dich TXC beim reinschreiben überhaupt nicht.
>
>  Erst beim letzten Zeichen kann das ev. von Interesse sein.

 Und falls du es unbedingt wissen musst:

 Beim letzten Zeichen TXC abwarten.

von Uhu U. (uhu)


Lesenswert?

Marc V. schrieb:
> Und falls du es unbedingt wissen musst:
>
>  Beim letzten Zeichen TXC abwarten.

Nochmal: Eine Bibliothek weiß i.A. nicht, ob gerade Zeichen ausgegeben 
werden, oder nicht. Einfach blind auf TXC zu pollen, funktioniert nicht, 
wenn man nicht u.U. ewig warten will.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Uhu U. schrieb:
>>  Beim letzten Zeichen TXC abwarten.
>
> Nochmal: Eine Bibliothek weiß i.A. nicht, ob gerade Zeichen ausgegeben
> werden, oder nicht. Einfach blind auf TXC zu pollen, funktioniert nicht,
> wenn man nicht u.U. ewig warten will.


 Nochmal:
 Auf TXC zu pollen wenn man irgendetwas ausgeben will, macht ganz
 einfach keinen Sinn. Man pollt auf UDRE0 und nicht auf TXC.
 Punkt.

 Und nochmal:
 Wenn dein Programm startet, ist USART mit Sicherheit nicht aktiv.

 Und zum letzten Mal:
 Nur wenn man sichergehen will, dass alles wirklich raus ist, prüft
 man auf TXC.
 Das kann aber nur bei mehreren Bussen mit Busdriver und ENABLE
 interessant sein.
 Da dies aber bei dir nicht der Fall ist...

: Bearbeitet durch User
von Uwe (Gast)


Lesenswert?

Hi,
>TXC zu pollen, funktioniert nur, wenn der UASART überhaupt aktiv ist,
>das ist also auch keine Lösung.
du kannst:
TXEN prüfen ob TX überhaupt aktiv
wenn ja, prüfe UDRE
wenn frei TXC löschen
warte Zeit für ein zu übertragendes Byte
teste TXC
wenn frei USART inaktiv

>• Bit 6 – TXC: USART Transmit Complete
>This flag bit is set when the entire frame in the Transmit Shift Register >has 
been shifted out and there are no new data currently present in the >transmit 
buffer (UDR).

viel Erfolg, Uwe

von Uhu U. (uhu)


Lesenswert?

Ich habe das Problem hier: 
Beitrag "Re: ATmega 328p USART: wird TXC auch automatisch gelöscht?" beschrieben - bitte 
nochmal nachlesen.

Marc V. schrieb:
> Auf TXC zu pollen wenn man irgendetwas ausgeben will, macht ganz
>  einfach keinen Sinn. Man pollt auf UDRE0 und nicht auf TXC.

Wenn das USART Data Register leer ist - also UDRE gesetzt wird -, steckt 
noch ein Byte im Shiftregister, dessen Ausgabe noch im Gang ist. Wenn 
man in diesem Moment den HC-05 in den AT-Mode schaltet, dann bekommt der 
dieses letzte Zeichen, oder Teile davon in den falschen Hals - wenn man 
den HC-05 also einigermaßen zuverlässig bedienen will, sollte man genau 
das vermeiden.

>  Punkt.

Ist doch eigentlich nicht so schwer, oder?

von Uhu U. (uhu)


Lesenswert?

Uwe schrieb:
> du kannst:
> TXEN prüfen ob TX überhaupt aktiv

Wenn TXEN gesetzt ist, heißt das nicht, dass der USART auch gerade 
Zeichen ausspucket - zumindest in der asynchronen Betriebsart.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Uhu U. schrieb:
> Ist doch eigentlich nicht so schwer, oder?

 Langsam lesen und versuchen zu verstehen:

Marc V. schrieb:
>  Und nochmal:
>  Wenn dein Programm startet, ist USART mit Sicherheit nicht aktiv.

 Danach irgendetwas senden, von mir aus nur "AT" (sollte man sowieso
 tun).

 Von da an prüft man vor jedem Befehl bzw. bevor man den entspr.
 Pin umschaltet, ob TXC gesetzt ist und setzt es zurück, egal ob das
 die Bibliothek oder dein Programm macht.

  Ist doch eigentlich nicht so schwer, oder?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wenn du eine (leere) ISR für TXC vorsiehst, dann wird es (wie
beschrieben) am Ende automatisch gelöscht.  Daher genügt es in
diesem Falle, TXC zu monitoren um zu wissen, ob im Schieberegister
gerade was passiert.

Sinnvoller wäre es natürlich, vor Beginn der Datenausgabe ein Flag
zu setzen und die ISR das Flag löschen zu lassen.  Dann kann man
das als Kriterium benutzen.

: Bearbeitet durch Moderator
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jörg W. schrieb:
> Wenn du eine (leere) ISR für TXC vorsiehst, dann wird es (wie
> beschrieben) am Ende automatisch gelöscht.  Daher genügt es in
> diesem Falle, TXC zu monitoren um zu wissen, ob im Schieberegister
> gerade was passiert.

 Hmmm.
 Wird man nie wissen, da es für main() so aussieht, als ob TXC niemals
 gesetzt wird.

von Thomas F. (igel)


Lesenswert?

Uhu U. schrieb:
> Thomas F. schrieb:
>> Steht doch eigentlich im Datenblatt zum USART Kapitel 24.7.1:
>
> Du kennst den Unterschied zwischen dem transmit buffer und dem
> shiftregister?

Ja.
Eventuell verstehe ich dein Problem nicht. Wenn man ein Byte über Uart 
senden will interessiert es doch nicht ob gerade noch ältere Bits 
rausgeshiftet werden.
Wichtig ist doch nur ob man das neue Byte schon ins UDR schreiben darf 
oder noch nicht.

Uhu U. schrieb:
> Einfach blind auf TXC zu pollen, funktioniert nicht,
> wenn man nicht u.U. ewig warten will.

Wenn man nicht warten will dann springt man eben zurück in die 
State-Machine und schaut ein paar Millisekunden später wieder vorbei.
Oder man nutzt den UDRE-Irq.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marc V. schrieb:
> Wird man nie wissen, da es für main() so aussieht, als ob TXC niemals
>  gesetzt wird.

Stimmt, Gedanke nicht bis zu Ende gedacht.

Dann funktioniert es nur mit dem Flag in der TXC-ISR.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Jörg W. schrieb:
> Marc V. schrieb:
>> Wird man nie wissen, da es für main() so aussieht, als ob TXC niemals
>>  gesetzt wird.
>
> Stimmt, Gedanke nicht bis zu Ende gedacht.
>
> Dann funktioniert es nur mit dem Flag in der TXC-ISR.

 Und ich war zu schnell mit der Antwort, dein Zusatz mit dem Flag
 war noch nicht da.

 Auf jeden Fall ist das mit dem Flag eine gute Lösung.
 Etwas abfragen muss er aber auf alle Fälle, ob TXC oder Flag ist
 eigentlich egal.
 Und ob er TXC zurücksetzt oder Flag setzt ist auch egal.

: Bearbeitet durch User
von Uhu U. (uhu)


Lesenswert?

Thomas F. schrieb:
> Eventuell verstehe ich dein Problem nicht. Wenn man ein Byte über Uart
> senden will interessiert es doch nicht ob gerade noch ältere Bits
> rausgeshiftet werden.

Den Empfänger - in diesem Fall der HC-05 BT-Adapter - interessiert das 
aber schon. Der schaltet nämlich einfach blind in den AT-Modus um und 
versucht dann mit einem mehr oder weniger halben Zeichen, das nicht für 
AT bestimmt war, irgendwas zu machen.

Jörgs Idee mit der ISR ist natürlich der perfekte Ausweg. Als ich 
gestern sah, dass die saubere Lösung etwas komplizierter ist, als 
erhofft, habe ich vor die Umschaltung in den AT-Modus einen Delay 
eingebaut - das ist die quick&dirty-Lösung, die funktioniert, so lange 
die Baudrate nicht zu gering ist.

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.