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
-- 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...
@ 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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.