mikrocontroller.net

Forum: Compiler & IDEs ISR(USART_TX_vect) atmega88 Verhalten


Autor: Alf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich es richtig verstehe, wird dieser Int immer dann ausgeführt, 
wenn 1 Byte komplett gesendet wurde, also wenn auch das Stop-Bit mit 
raus ist.

Wenn ich mehrere Bytes unmittelbar hintereinander sende, löst der Int 
bei mir nicht nach jedem Einzelbyte aus, sondern nur wenn das letzte 
eines Blockes raus ist. Ist dieses Verhalten immer so, oder von mega zu 
mega anders? Hat vermutlich was mit der Pipline zu tun. Ich könnte damit 
leben.

Autor: Sash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

im Datenblatt steht:
The Transmit Complete (TXCn) Flag bit is set one 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.
The TXCn Flag bit is automatically cleared when a transmit complete interrupt is executed, or it
can be cleared by writing a one to its bit location. The TXCn Flag is useful in half-duplex communication
interfaces (like the RS-485 standard), where a transmitting application must enter
receive mode and free the communication bus immediately after completing the transmission.
When the Transmit Compete Interrupt Enable (TXCIEn) bit in UCSRnB is set, the USART
Transmit Complete Interrupt will be executed when the TXCn Flag becomes set (provided that
global interrupts are enabled). When the transmit complete interrupt is used, the interrupt handling
routine does not have to clear the TXCn Flag, this is done automatically when the interrupt
is executed.

Ich bin kein wirklich erfahrener Nutzer ... aber mein erster Versuch das 
von Dir beschriebene Verhalten zu ändern wäre, ein neues Byte erst in 
den Puffer zu schreiben wenn der Transmit Complete Interrupt 
angesprungen wurde (z.B. indem man in genanntem Interrupt ein flag 
setzt, auf das die Funtion die die Bytes in den Transmitpuffer schreibt 
wartet).

^^ Falls hier grobe Fehler vorliegen kann der Beitrag bitte gelöscht 
werden ... ist das erste Mal das ich antworte statt nur selber zu 
Fragen, um auch mal was beizutragen. Hoffe es ist nicht ganz falsch was 
ich geschrieben habe.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der TXC-Interrupt löst aus, wenn der Tx-Teil des UARTs arbeitslos ist. 
Es stehen dann keine neuen Daten zum Senden mehr an und das letzte 
Zeichen ist komplett hinausgeschoben.  Dieses Verhalten ist für alle 
AVRs gleich (und nicht nur dort).  Die Hauptanwendung ist die Steuerung 
von externer Sendehardware, z.B. das Abschalten des RS485-Sendetreibers.

Der Interrupt, der bei jedem Zeichen auslöst, heißt beim AVR UDRE.  Der 
zeigt an, dass der UART in der Lage ist, ein neues Sendezeichen zu 
akzeptieren, also (in CPU-Größenordnungen) lange bevor das letzte 
Zeichen komplett abgesendet ist.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Alf (Gast)

>wenn 1 Byte komplett gesendet wurde, also wenn auch das Stop-Bit mit
>raus ist.

Nicht ganz, wenn das letzte Byte gesendet wurde und kein neues Datenbyte 
im Sendepuffer liegt.

>Wenn ich mehrere Bytes unmittelbar hintereinander sende, löst der Int
>bei mir nicht nach jedem Einzelbyte aus, sondern nur wenn das letzte
>eines Blockes raus ist.

So soll das auch sein.

> Ist dieses Verhalten immer so,

Ja.

> oder von mega zu
>mega anders? Hat vermutlich was mit der Pipline zu tun. Ich könnte damit
>leben.

Siehe 
http://www.mikrocontroller.net/articles/Interrupt#...

MFG
Falk

Autor: Alf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok dann passt es. Es geht um RS-485 Sender Ein- und Ausschaltung. Die 
soll erst nach dem letzten Byte sein.

Autor: Ulrich P. (uprinz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nur als Hinweis:

Wenn Deine Software noch andere Dinge per Interrupt tut, kann es 
passieren, dass Du vereinzelt auch TXC Interrupts bekommst, obwohl noch 
weitere Zeichen zu senden wären. Das passiert immer dann, wenn die 
Software z.B. ein cli() macht, einie zeit benötigt und dann sei() gibt 
und innerhalb dieser Zeit der Zustand UDRE und danach TXC auftritt wegen 
der gesperrten Interrupts

Es ist daher sinnvoll die Zeichen per UDRE Interrupt aus dem Puffer in 
das UDR zu schieben und dort auf das letzte Zeichen zu prüfen. Wenn es 
das letzte Zeichen ist, den TXC Interrupt aktivieren, den UDRE Interrupt 
deaktivieren.

Der TXC Interrupt schaltet dann den RS4xx Bus um und deaktiviert sich 
selbst.

D3er UDRE Interrupt wird in der putc() erneut aktiviert, wenn erneut 
Zeichen zu senden sind.

Gruß, Ulrich

Autor: Alf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Nur als Hinweis:

Danke für die Infos, gut mal von dem Verhalten gehört zu haben.

Bisher läuft es ohne Probleme. TXC Int. kommt zeitlich korrekt. Habe 
auch noch andere Interrupts laufen. Allerdings vermeide ich generell in 
einem Programm die zeitweise globale Interruptsperrung mit cli/sei.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.