mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik TX UART Problem Peter Fleury


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein Problem mit der UART Lib von Peter Fleury:
void uart_putc(unsigned char data)
{
    unsigned char tmphead;

    
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
    
    while ( tmphead == UART_TxTail ){
        ;/* wait for free space in buffer */
    }
    
    UART_TxBuf[tmphead] = data;
    UART_TxHead = tmphead;

    /* enable UDRE interrupt */
    UART0_CONTROL    |= _BV(UART0_UDRIE);

}/* uart_putc */

Wenn ich mittels uart_puts("dsadkljK") etwas verschicken will bleibt der 
Controller auf der Zeile
while ( tmphead == UART_TxTail ){ 
stehen. In beiden Variablen steht dann eine 0x12...

Wieso ist das so? Wieso while() ohne darin was zu tun?

Vielleicht kann mir jemand weiterhelfen, in jedem Fall vielen Dank!
Thomas

Autor: Stefan B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Programm wartet - wie dokumentiert - an dieser Stelle, weil im 
Sendepuffer momentan kein weiterer Platz ist. Weiterer Platz wird erst 
geschaffen, wenn Zeichen von der UDRE Interruptroutine gesendet werden.

In deinem unbekannten Programm werden anscheinend von der UDRE 
Interruptroutine keine Zeichen gesendet. Das kann an einem Fehler im 
selbst geschriebenen Programmteil liegen, den wir nicht sehen. 
Möglicherweise die Fleury Library ist von dir nicht richtig 
initialisiert und/oder Interrupts sind noch nicht global aktiviert.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wahrscheinlichste ist, dass an der Stelle die Interrupts nicht 
aktiviert sind, entweder weil sie explizit deaktiviert sind, oder 
implizit. Du versuchst nicht etwa innerhalb einer ISR was zu senden, 
oder?

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm gute Frage mit in einer ISR. Ich rufe aus einem Timer eine Funktion 
auf die dann was ausgeben will... das zählt dann wohl als aus einer ISR.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In einer ISR werden grundsätzlich keine länger andauernden Operationen 
durchgeführt. Weder wird auf irgendetwas gewartet, noch macht man 
Ausgaben. Das ist eine einfache Regel, die nur dann zu Problemen führt, 
wenn man sie nicht beachtet.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja drum hätte ich ja auch gerne ein paar Zeichen in den Ausgangspuffer 
geschrieben und fertig.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> Naja drum hätte ich ja auch gerne ein paar Zeichen in den Ausgangspuffer
> geschrieben und fertig.

Das funktioniert aber nur, wenn auch entsprechend Platz im Puffer ist. 
Wenn kein Platz mehr ist, hast du den von dir beobachteten Deadlock.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja danke euch beiden... Da muss ich wohl was umbauen.

Autor: daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mach doch so ...
uINT8 flags;
#define SHOULD_SEND    0
#define SHOULD_DO_XYZ  1
...


ISR(..._vect) {
    flags |= 1UL << SHOULD_SEND;
}

int main(void) {
    while(1) {
        if(flags & (1UL << SHOULD_SEND)) {
            flags &= ~(1UL << SHOULD_SEND);
            call_send_routine();
        }
        // ...
    }
}

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Löschen des Flags muss/müssen der/die Interrupt/s gesperrt werden. 
Man kann auch statt den Flags + Interrupts nur das Interruptflag 
abfragen in der main-loop (Aber dann die Interrupts deaktivieren).

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja ich habe in etwa die Lösung von Daniel umgesetzt.
Ich setzt nur noch Flags in der ISR für 10/100ms Tasks die dann in der 
Main abgearbeitet werden...

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.