AVR-UART-Ausgabe kommt oft aus dem Takt

Gast #1160738
Lesenswert?

Hallo,

in meinem AVR-Programm für einen ATmega16 möchte ich alle 20ms Werte 
über die Serielle Schnittstelle ausgeben. Das klappt vom Prinzip her 
auch. Nur manchmal hängt sich der AVR auf. Ich vermute mal, dass die 
while-Schleifen der UART-Ausgabe-Funktionen(siehe unten) schuldig sind 
(die restlichen Funktionen waren bis auf die Timer-ISR auskommentiert).

Gibt es eine geschickte Möglichkeit dieses Aufhängen zu verhindern?


Sebastian
1
// bei neueren AVRs andere Bezeichnung fuer die Statusregister, hier ATmega16:
2
int uart_putc(unsigned char c)
3
{
4
    while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich 
5
    {
6
    }                             
7
 
8
    UDR = c;                      // sende Zeichen 
9
    return 0;
10
}
11
 
12
 
13
// puts ist unabhaengig vom Controllertyp 
14
void uart_puts (char *s)
15
{
16
    while (*s)
17
    {  //  so lange *s != '\0' also ungleich dem "String-Endezeichen" 
18
        uart_putc(*s);
19
        s++;
20
    }
21
}
#1160753
Lesenswert?

Sebastian wrote:
>     while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
>     {
>     }
>
>     UDR = c;                      // sende Zeichen
>     return 0;

Fehlt da nicht ein NOP oder wenigstens ein Semikolon? Für mich sieht das 
so aus, als ob du Daten in das UDR schreibst, solange das Senden eben 
nicht möglich ist.

PS: Je länger ich mit {} angucke, desto unsicherer bin ich mir. 
Verwertet der Compiler dies als ;?
Gast #1160781
Lesenswert?

Der AVR arbeitet mit einem externen Quarz, nich mit dem internen 
Quarzosz..

Ich hab es auch ohne einen PC nur mit dem Scope angeschaut, da sieht man 
es deutlich, dass er da ein Kaffeepäuschen von ca. 300ms ab und an 
macht.
Gast #1160795
Lesenswert?

@Sven '\0':

Da hast du natürlich recht gehabt. nun hab ich des mal berichtigt:

while (!(UCSRA & (1<<UDRE)))  // warten bis Senden moeglich
{
  asm volatile("nop");
}

aber, er macht immer noch seine kleinen 300ms-Päuschen :-(
Gast #1160851
Lesenswert?

>PS: Je länger ich mit {} angucke, desto unsicherer bin ich mir.
>Verwertet der Compiler dies als ;?

Das eine ist leerer Block, das andere eine leere Anweisung. Der Effekt 
ist allerdings der gleiche.

Oliver
#1160954
Lesenswert?

@Sebastian (Gast)

>Kaum nimmt man die Optimierungsstufe des guten AVR-Studios bzw. des
>GNU-Compilers zurück und setzt die Timer Variablen auf volatile, schon
>gehts auch deutlich stabiler.

Dann liegt der Fehler wie vermutet bei dir. Poste mal vollständigen 
Code.

MFG
Falk

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren