www.mikrocontroller.net

Forum: Compiler & IDEs XMega UART, DataregisterEmpty


Autor: Hans Josef (hjm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe da ein Problem.

Ich nutze einen ATXmega 128A1 und sende damit im Interrupt via UARTC1.

Wenn ich den TXC-Interrupt wähle funktiniert es einwandfrei.

Ich möchte jedoch den DRE (DataRegisterEmpty) Interrupt nutzen, um
die Kommunikation Schlupffrei zu machen.

Jedoch funktioniert dies nur ein einziges mal nach einem Reset
und danach werden keine Daten mehr gesendet.

Gibt es da irgend welche Probleme bei den XMega's?

Grüße
Hans-Josef

Autor: Mike R. (thesealion)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gib doch mal ein wenig mehr von deinem Code preis.

Autor: Hans Josef (hjm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

hier mal etwas Code.
Zuerst die Version mit TXC-IRQ, welche einwandfrei funktioniert:
#define COM_C1 USARTC1        // USART1 von PORTC wird als Interface Bus1


mstr_send;         // Receive OFF, Sender ON, Datenrichtung=Senden
uart_send_cnt = 6; // Anzahl zu sendender zeichen
uart_cnt      = 0; // Zeichenzähler

USART_PutChar(&COM_PB, uart_buffer[uart_cnt++]);  // Sende 1.char
USART_TxdInterruptLevel_Set(&COM_C1, USART_TXCINTLVL_HI_gc);  // Trans-IRO scharf machen
...

...
ISR (USARTC1_TXC_vect)  // Send IRQ
{
  if (uart_cnt < uart_send_cnt)                        // Alles gesendet?
    USART_PutChar(&COM_C1, uart_buffer[uart_cnt++]);  // TX Buffer fuellen

  else{
    PORTC.OUTCLR = PIN5_bm;      // RS485 Datenrichtung Empfang
    USART_Tx_Disable(&COM_C1);   // TX_disable
  }
}


Jetzt mit DRE-IRQ, welches nur einmal funktioniert. Dabei sollte immer 
wenn das Datenregister leer ist was eingetragen werden und am Schluß 
wird dann der TXC-IRQ scharf gemacht, was die RS485-Datenrichtung 
umschaltet und den Sender abschaltet.
#define COM_C1 USARTC1        // USART1 von PORTC wird als Interface Bus1


mstr_send;         // Receive OFF, Sender ON, Datenrichtung=Senden
uart_send_cnt = 6; // Anzahl zu sendender zeichen
uart_cnt      = 0; // Zeichenzähler

USART_DreInterruptLevel_Set(&COM_C1, USART_DREINTLVL_HI_gc);  // Trans-IRO scharf machen

ISR (USARTC1_DRE_vect)  // Send IRQ
{
  if (uart_cnt < uart_send_cnt)                        // Alles gesendet?
    USART_PutChar(&COM_C1, uart_buffer[uart_cnt++]);  // TX Buffer fuellen

  else{
    USART_DreInterruptLevel_Set(&COM_C1, USART_DREINTLVL_OFF_gc);  // DRE-IRQ sperren
    USART_TxdInterruptLevel_Set(&COM_C1, USART_TXCINTLVL_HI_gc);  // Trans-IRO scharf machen
  }
}

ISR (USARTC1_TXC_vect)  // Ende des senden
{
  PORTC.OUTCLR = PIN5_bm;      // RS485 Datenrichtung Empfang
  USART_Tx_Disable(&COM_C1);   // TX_disable
}

Also wie gesagt die erste Lösung arbeitet (bis auf die kleinen) 
Verzögerungnen durch andere IRQ-Bearbeitung.
Die DRE-Lösung tut es nur bei erstenmal nach einem Reset, danach sendet 
der µC nichts mehr????

Ich habe spaßeshalber mal ein Senden im Pollbetrieb gemacht, mit dem 
gleichen Ergbnis.


Grüße
Hans-Josef

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Nach Reset ist das DRE-Bit gesetzt, die Routine wird also nach Freigabe 
der IRQ sofort aufgerufen.

Du schaltest dann den DRE-IRQ in der ISR aus.
Irgendwann sicher auch wieder ein?

DRE ist nach Schreiben der Daten in der ISR gelöscht, das wird auch nie 
wieder gesetzt, es sei denn, Du schreibst das erste Byte zum erneuten 
Senden
außerhalb der ISR in den UART, dann wird es gesetzt, wenn die Daten raus 
sind.

Gruß aus Berlin
Michael

Autor: Hans Josef (hjm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so ich habe den Fehler gefunden.

Wenn man den Transmitter abschaltet wenn noch Zeichen im Schieberegister 
sind dann funktioniert der Tansmitter danach garnicht mehr.

Hat jemand eine Ahnung, wie man den Transmitter wieder zurücksetzen 
kann?


@amiga,
Der DRE-IRQ wird immer ausgeführt, da das Flag nur gelöscht wird wenn 
man Daten schreibt. Löschen kann man das nicht.
Wenn man den DRE-IRQ nicht sperrt dann kommt der immer.
So steht's auch im Manual beschrieben.

Grüße
Hans-Josef

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.