mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART-Übertragung - Wartezeit?


Autor: Björn Moosmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe ein kleines Problem... Und zwar möchte ich an meinen
Mikrocontroller (AT90S8515) ein Zeichen senden, worauf mir dann der µC
mehrere Bytes zurücksenden soll.
Das vom PC per Hyperterminal gesendete Zeichen kommt an, die
zurückgeschickten Daten sind jedoch verstümmelt.
Dies liegt wohl daran, dass die UART nicht so schnell senden kann wie
ich Daten ins UDR schiebe. Also habe ich versucht mittels TXC bzw.
UDRE-Bit zu warten, bis die UART wieder frei ist. Beides jedoch ohne
Erfolg. Mittels einer festen Zeitverzögerung klappt es.
Was muß ich tun, damit auch die saubere Lösung mit Ausertung der
Statusbits funktioniert?

Vielen Dank!
Björn


Mein Sourcecode:

unsigned char x = 0;
while (RX_Text[x] != '\0')
{
  UDR = RX_Text[x];
  x++;

  unsigned char y = 4;    //mit manueller Schleife funktionierts
  while (y >0)
  {
                time();
    y--;
  }
//  while (!TXC)           // Bit-Auswertung geht nicht... :-(
//  {
//    asm volatile ("nop");
//  }
}

Autor: Anton Wert (antonwert)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch doch mal die Daten im UART-Data-Register-Empty-Interrupt zu
senden (immer eins pro Interrupt). Dann muss es klappen.
Tipp: falls das Senden beendet ist einfach Interrupt deaktivieren.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> while (!TXC)

TXC ist bloss die Bitnummer im Register, diese zeile ist also
äquivalent zu sowas wie "while(1)".

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe von C keine Ahnung, aber die Abfrage von UDRE geht hier schon
immer.

uart_send:
        sbis    UCSRA,UDRE                  ; Send-Register leer ?
        rjmp    uart_send                    ; nein

        out     UDR,TEMP_A
        ret

Gruß aus Berlin
Michael

Autor: Björn Moosmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ A.K.

Vielen Dank, jetzt klappt es!

Hab die entsprechende Zeile geändert:

    while (!USR && BITPOS_6)

wobei BITPOS_6 mit 0x40 definiert ist.

Gruß
Björn

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erstaunlich, dass das funktioniert. Guck noch mal in dein C Buch rein.
Beispielsweise unter den Operatoren "&&" und "&".

Empfehlen würde ich eher die Version
  while (!(USR & BITPOS_6))
wobei UDRE (oder was auch immer für ein Bit das ist) sicher lesbarer
ist als BITPOS_6.

Autor: Olaf Kindel (olaf_k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens macht man sowas besser mit einem FIFO (= Ringpuffer) und per
Interrupt.
Prinzip: Alle zu sendenden Zeichen kommen in den FIFO, und der
UDRE-Interrupt wird freigegeben. In der UDRE-ISR wird jedesmal, wenn
der UART "frei" ist, ein Zeichen aus dem FIFO geholt und ins UDR
geschrieben. Wenn der FIFO leer ist, deaktiviert sich der Interrupt
selbst.
Vorteil: Man schreibt nur einmal die Daten in den FIFO, den Rest macht
die ISR dann von alleine, d.h. man verschwendet keine Zeit mit
Warteschleifen. Der µC kann z.B. auch schon wieder neue Daten empfangen
und verarbeiten, während er noch "alte" Zeichen aus dem FIFO sendet.

MfG Olaf

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Olaf: Mal sachte, er macht grad seine ersten Gehversuche.

Autor: inoffizieller WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>while (!USR && BITPOS_6)
>Erstaunlich, dass das funktioniert.

!USR invertiert USR logisch: Alles, was ungleich 0 (wahr) ist, wird zu
0 (falsch).
BITPOS_6 ist immer wahr (könnte man sich also auch sparen).
Wenn also in USR irgendwas passiert (also irgendein Bit gesetzt
wird), wird die Schleife verlassen.

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.