Forum: Mikrocontroller und Digitale Elektronik AVR315 mit Warteschleifenproblem


von Franz J. (francesco)


Angehängte Dateien:

Lesenswert?

Hallo,

nachdem ich erfolgreich eine TWI-Kommunikation mit zwei Atmega16 
aufgebaut habe, bei der der Master im Polling-Modus und der Slave mir 
Interrupts arbeitet, war mein nächstes Ziel auch den Master über 
Interrupt anzusteuern. Als Unterlage hierfür habe ich die Appnote AVR315 
von Atmel genommen und den IAR-Code für den von mir verwendeten 
GCC-Compiler umgeschrieben. Das hat soweit auch gut funktioniert, nur 
gibt es nun ein kleines Problem, das ich mir nicht erklären kann.

Laut Appnote 315 steht in der main-Routine ziemlich am Ende

// Do something else while waiting for the TWI Transceiver to complete 
the current operation
__no_operation(); // Put own code here.

Wenn ich jedoch hier eine Warteschleife von 50 ms oder länger (bei einem 
Bustakt von 500 Hz) eingebe, reagiert der Slave nicht mehr und auch der 
Master initiiert das Senden nicht erneut.
Hinweis: Für Testzwecke stoße ich nur das Senden zum Slave an - habe 
also das Receive und Request laut AVR315 gesperrt.
Der Slave besteht aus einem simplen Programm, wo bei Auftritt eines 
TWI-Interrupts nur die empfangenen Daten auf dessen UART-Schnittstelle 
ausgegeben werden; er sendet somit außer ACK nichts an den Master 
zurück.

Um das Problem einzukreisen, habe ich mir die Empfangsdaten des Slave 
angesehen. Es handelt sich immer um vier Zeilen, die mit dem Acknowledge 
beginnen und dem Stopp enden.
Als Klartext mit zugehörigem Statuscode ergibt sich folgende 
Darstellung:

SR:ACK sent    0x60
SR:Data received - ACK  0x80
SR:DATA:a    Datenbyte 1
SR:STOP received  0A0

SR:ACK sent    0x60
SR:Data received - ACK  0x80
SR:DATA:b    Datenbyte 2
SR:STOP received  0A0

Im Falle der Wartezeit kommt das STOP des Masters nicht mehr, ab hier 
hängt dann der Slave in der main-Schleife und ruft den ISR nicht mehr 
auf, d. h. der Bus ist tot.

Wer hat eine Erklärung hierfür; normalerweise müsste doch der TWI-Bus 
nach Verlassen des ISR wieder gestoppt sein und damit sollte eine 
beliebig lange Wartezeit in der main() keine Probleme verursachen?

Im Anhang findet sich ein Ausschnitt des Programmcodes, wobei ich der 
Übersicht halber nur die relevanten Teile angeführt habe, im Prinzip 
entspricht alles der Appnote 315.
Interessanterweise funktioniert eine Wartezeit im 
Fehlerbehandlungsabschnitt (zwischen ISR und main), wo ich mal testweise 
5 Sekunden eingegeben habe.


Vielleicht hat jemand ein ähnliches Problem und kennt die Lösung?

francesco

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

-- Was war denn der letzte Zustand (TWSR) in der ISR?
-- Taucht das Problem auch bei kleineren Wartezeiten auf?
-- Wie initiiert Du das STOP am Ende der zu empfangenden Daten, seh ich 
irgendwie net...

von Franz J. (francesco)


Lesenswert?

@ Georg Johann Lay,

Der Stopp kommt über die ISR-Routine (siehe (1<<TWSTO).
Wie gesagt, es handelt sich um die Original-AVR315, nur für gcc 
umgeschrieben. Bei Wartezeiten unter 50ms (bei 500 Hz Bustakt) gibt es 
keine Probleme.

francesco

von Michael S. (Gast)


Lesenswert?

was macht den dein wait_ms() ??
Ruft doch bestimmt _delay_ms() auf.
Womöglich noch mit einer Variablen als Parameter ?

Versuchs doch mal mit:

void wait(uint8_t t)
{
uint8_t i;

for (i = 1; i < t; i++)
{
_delay_ms(1);  // Konstante als Parameter
}
}

Sollte das nicht helfen, dann liegt die Ursache an anderer Stelle.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.