Forum: Mikrocontroller und Digitale Elektronik Reset Master (Library Peter Fleury), TWI hängt sich auf


von Markus E. (master_2)


Lesenswert?

Hallo Zusammen,

mein TWI-Bus funktioniert soweit einwandfrei (Libary Peter Fleury). Am 
TWI- Bus ist ein Master (Atmega32) und zwei Slaves (ATmega32) 
angeschlossen. Beim Betätigen der Resettaste vom Master hängt sich der 
Bus im Schritt

** Wait until transmission completed*/
  while (!(TWCR & (1<<TWINT)));

auf. Wenn ich den Slave zurücksetze, funktioniert der Bus wieder. Für 
mich ist dieses Verhalten nicht akzeptabel, da ich nicht jedesmal den 
Slave zurücksetzen möchte. Ist dies ein Softwarefehler in der Peter 
Fleury Libary.

Vielen Dank!

von stefanus (Gast)


Lesenswert?

Wenn sich der Bus aufhängt, ist der Bus defekt oder einer der daran 
hängenden Teilnehmer. Welchen Pegel haben denn SCL und SDA während es 
hängt? Sollte High sein. Wenn es nicht High ist, dann suche den Fehler 
in der Hardware oder den angeschlossenen Geräten.

von dummy (Gast)


Lesenswert?

>auf. Wenn ich den Slave zurücksetze, funktioniert der Bus wieder. Für
>mich ist dieses Verhalten nicht akzeptabel, da ich nicht jedesmal den
>Slave zurücksetzen möchte.

Dann resette den Master nicht im laufenden Betrieb.

>Ist dies ein Softwarefehler in der Peter
>Fleury Libary.

Ein Fehler ist es nicht. Der Peter hatte eben nicht
vor einen hotswap fähigen Code zu schreiben.

von Markus E. (master_2)


Lesenswert?

Ich habe jetzt noch mal die Software überprüft. Im Punkt

** Wait until transmission completed*/
  while (!(TWCR & (1<<TWINT)));

bleibt der Master ohne Busteilnehmer nicht hängen (auch nach Reset vom 
Master, das Program läuft weiter). Wenn ich die  Bussteilnehmer (2 
Slaves) anschliesse und an dieser Stelle einen Breakpoint setze, und es 
debugge, funktioniert das Programm, auch nach einem RESET vom Master. 
Sobald ich das Programm ohne Debuggmode wieder laufen lasse und dann den 
Master resette,  hängt sich dieser wieder auf. Das Programm (Master) 
kann erst durch Reset der Busteilnehmer wiederbelebt werden.

Wer ist eigentlich verantwortlich, dass wir aus dieser Schleife springen 
while (!(TWCR & (1<<TWINT))). Die Busteilnehmer können es ja nicht sein, 
da das Programm ja ohne Slaves funktioniert.

Auch ist es komisch, dass es im Debuggmode funktioniert.

Vielen Dank!

von Oliver R. (orb)


Lesenswert?

Warscheinlich hält einer der Slaves SDA auf Low weil er mitten in der 
Übertragung war und der Master wartet jetzt ewig darauf das er fertig 
wird. Ohne Slaves kann das nicht passieren.
Wie Stefanus schon schrieb, sieh Dir mal die Pegel nach den Reset an.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Der Master kann einen I²C-Bus mit einer bestimmten Sequenz zurücksetzen. 
Mache ich immer so nach einem Restart. Ist zum Beispiel dann sinnvoll, 
wenn ein batteriegepufferte RTC mit am Bus hängt und da noch nichtmals 
ein Power-Off aller Teilnehmer was bringt.

von Peter D. (peda)


Lesenswert?

Markus Engelhofer schrieb:
> Ist dies ein Softwarefehler in der Peter
> Fleury Libary.

Nein, das ist ein Fehler in der TWI-Implementation von Atmel, es gibt 
keine Bus-Reset Funktion.

Der Slave kriegt ja nicht mit, wenn der Master resettet und er kann z.B. 
gerade Datenbit 0 oder ein ACK auf den Bus legen, d.h. er zieht SDA auf 
low.

Da nun das Master-TWI keine Resetfunktion hat, muß man den Bus händisch 
rücksetzen.
Dazu muß man das Master-TWI disablen und mit einem SW-I2C bis zu 9-mal 
versuchen, ein Stop zu senden und bei Mißerfolg einen SCL Takt-Zyklus 
einfügen.

Sind nur Slaves mit MC angeschlossen, können diese auch einen Timeout 
aufsetzen und z.B. nach 10ms SDA = 0, sich selber disablen und damit SDA 
wieder freigeben.

von Markus E. (master_2)


Angehängte Dateien:

Lesenswert?

Programm funktioniert ohne Fehler, wenn der Reset-Button am Master nicht 
betätigt ist. Wird im Debuggmode der RESET betätigt, funktioniert das 
Programm auch.  Der Master hängt sich nicht auf.
Programmablauf  kein Fehler (Software Fleury):

1.  Zu Beginn: SDA + SCL -> High

2.  Aufruf der Funktion  TWIM_Start ()

3.  In der Funktion TWIM_Start: while (!(TWCR & (1<<TWINT)));
    -> Dann SDA + SCL -> Low

4.  In der Funktion TWIM_Start: while (!(TWCR & (1<<TWINT)));
    -> SDA = High, SCL=Low

5.  Aufruf der Funktion TWIM_ReadAck ()

6.  In der Funktion TWIM_READ AcK: while (!(TWCR & (1<<TWINT)));
    ->SDA + SCL= Low

7.  Aufruf der Funktion TWIM_ReadNack()

8.  In der Funktion TWIM_ReadNack:  while (!(TWCR & (1<<TWINT)));
    -> SDA= High, SCL= Low

9.  Aufruf der Funktion TWIM_Stop()

10.  In der Funktion TWIM_Stop: while (!(TWCR & (1<<TWINT)));
    -> SDA + SCL -> High


Läuft das Programm ohne Fehler,  schaut der Bus wie gezeigt in den 
Bildern (Bus_TWI, Bus_TWI_zoomed) aus.  Wird jetzt die Reset-Taste auf 
dem Master betätigt,  bleibt SCL und SDA auf LOW. Der Master hängt sich 
auf. Dies verstehe ich nicht, weil der Master im Debuggmode sich nicht 
aufhängt.

Kann es vllt. daranliegen, das der Master im Debuggmode mehr Zeit hat 
für die Bearbeitung?

Ich bitte um Antwort und Tipps zur Fehlerbehebung.

Mit freundlichen Grüßen

von Mark R. (stevestrong)


Lesenswert?

Hast du alle internen pull-up Wiederstände aktiviert?
Es schein merkwürdig dass SDA und SCL selten auf "high" stehen, obwohl 
das eigentlich das "default" zustand sein sollte.
Nach dem RESET ich würde einfach mal per SW 9 pulse auf der SCL Leitung 
generieren (pin toggeln). Hier auch zuerst pull-up Wiederstände 
aktivieren. Das sollte die Slaves aus einem undefiniertem Zustand 
rausbringen. Und erst danach TWI initialisieren.

: Bearbeitet durch User
von Markus E. (master_2)


Lesenswert?

Ich habe externe Pull-up Widerstände verwendet.

von Jörg T. (kallejoerg)


Lesenswert?

Hallo Mark,

ich arbeitet gerade an einen ähnlichen Problem. Ich habe ein Arduino 
mega 2560 (Atmel ATmega640) und nutze die Arduino libraries von Todd 
Krein (wire & twi).

Bei einem simulierten Fehler z.B. SDA Leitung und SCL Leitung versucht 
der Bus eine stop-condition auszuführen. Im TWSR Register kommt auch 
dieser Befehl an, nur den TWSTO-Bit im TWCR Register wird nicht 
zurückgesetzt und der Bus sowie mein Programm hängt sich in eine 
ähnliche while-Schleife auf [ while(TWCR & (1<<TWSTO)); ].
Ich suche nach einem möglichen Rückgabewert bzw. ein Möglichkeit 
Bus-Stop, damit mein Programm sinnvoll arbeitet und damit umgehen kann.

Zurück zu dir:

** Wait until transmission completed*/
  while (!(TWCR & (1<<TWINT)));

Laut Datasheet ATmega32 - page 177:
"The TWINT Flag must be cleared by software by writing a logic one to 
it."

Kann es sein, dass durch den Reset deine Logic nicht mehr funktioniert 
und somit den TWINT-Bit HIGH setzen kann? Konntest du in der ISR dein 
letzten TWSR Status mal auslesen?

Beste Grüße
Jörg

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.