TX UART Problem Peter Fleury

Gast #1535194
Hallo,

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

5
    
6
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
7
    
8
    while ( tmphead == UART_TxTail ){
9
        ;/* wait for free space in buffer */
10
    }
11
    
12
    UART_TxBuf[tmphead] = data;
13
    UART_TxHead = tmphead;
14

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

18
}/* uart_putc */

Wenn ich mittels uart_puts("dsadkljK") etwas verschicken will bleibt der 
Controller auf der Zeile
1
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
Gast
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.
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.
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.
Gast
mach doch so ...
1
uINT8 flags;
2
#define SHOULD_SEND    0
3
#define SHOULD_DO_XYZ  1
4
...
5

6

7
ISR(..._vect) {
8
    flags |= 1UL << SHOULD_SEND;
9
}
10

11
int main(void) {
12
    while(1) {
13
        if(flags & (1UL << SHOULD_SEND)) {
14
            flags &= ~(1UL << SHOULD_SEND);
15
            call_send_routine();
16
        }
17
        // ...
18
    }
19
}
Gast
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

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.