Forum: Mikrocontroller und Digitale Elektronik einfachstmögliche Fehlerbehandlung I2C gesucht


von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo allerseits,

ich lasse einen AVR über das TWI auf ein I2C-Display schreiben. Am Bus 
hängen noch ein unbenutztes EEPROM und ein PCF8574, der angesteuert 
wird. 2 x 4,7 k zum + . Läßt man aufs Display dauerhaft Daten schreiben, 
so daß sich auf dem Bildschirm ständig etwas ändert, bleibt das Programm 
irgendwann hängen.

Die Aussetzer zeigen sich nach unterschiedlich langer Zeit und können 
gleich zu Anfang oder erst nach 100000 Zugriffen auftreten und sind 
unabhängig vom TWI-Takt. Zwischen 10 kHz und 200 kHz bleibt das 
Verhalten gleich.

Im Programm ist bisher keinerlei Fehlerbehandlung mittels Auswertung des 
TWISR enthalten. (quick & dirty)

Was wäre denn die einfachtsmögliche Fehlerbehandlung? Ich möchte Fehler 
nicht ausgleichen, sondern nur, daß der AVR weiter macht.

Gut, es gibt umfangreiche Appnotes, die mir aber direkt nichts nützen.

Hier beispielsweise hat schon mal jemand eine einfache Lösung 
angewendet:
Beitrag "Korrekte I2C Fehlerbehandlung (AVR)"

Woher kommen eigentlich solche Störungen? Werden sie eingestreut aus der 
Umgebung (ist hier keine Industrieumegbung) oder kommt der Slave 
irgendwann durcheinander?

Schon mal danke für die Antworten.
mit freundlichem Gruß

von spess53 (Gast)


Lesenswert?

Hi

>Woher kommen eigentlich solche Störungen? Werden sie eingestreut aus der
>Umgebung (ist hier keine Industrieumegbung) oder kommt der Slave
>irgendwann durcheinander?

> 2 x 4,7 k zum +

Kann durchaus schon zu hoch sein. Lies mal hier:

www.nxp.com/documents/user_manual/UM10204.pdf

MfG Spess

von Pandur S. (jetztnicht)


Lesenswert?

Man schreibt doch sowieso mit dem Timer auf den Display.
Und dann schreibt man immer ohne Warten.
So kann nichts haengenbleiben.

von Joachim B. (jar)


Lesenswert?

mir war mal so das I2C am AVR nicht mit clock stretching zusammengeht, 
da könnte man mit einem anderen Port warten ob SCL wieder high geht.

Bei Nutzung von I2C EEPROMs hatte ich keinen Erfolg das busy am Arduino 
abufragen, ergo polle ich das EEPROM solange bis es wieder ohne error 
antwortet, das erspart mir zumindest die sonst immer programmierte 
Wartezeit von 5-10ms die ich bis jetzt in jedem Beispiel fand.

Ein komplettes Beschreiben geht dann deutlich schneller.

von Joachim B. (jar)


Lesenswert?

Christian S. schrieb:
> Läßt man aufs Display dauerhaft Daten schreiben

ist IMHO sowieso unsinnig, ich schreibe nur alle 250ms aufs Display, 
schneller kann ich eh nicht lesen!

Damit ich mir da keinen Kopf machen muss schreibe ich die Daten in einen 
Rambereich so oft wie nötig und kopiere den RAM nur 4x / s ins Display

von Amateur (Gast)


Lesenswert?

I²C Fehler haben normalerweise zwei Quellen:
1. Fehler die sich aus der Ansteuerung (Programm) ergeben.
2. Fehler die sich aus der Elektrik ergeben.
Nummer eins kann sehr viele Ursachen haben. Der gute, alte Stack 
Overflow, der je nach Situation sehr schnell auftreten kann, aber auch 
erst nach Stunden. Die "Einheitsansteuerung" (I²C) von Schaltkreisen, 
die aber unterschiedliche Abfragesequenzen benötigen.
Die meisten Schaltkreise haben recht fein gestufte Fehlermeldungen, die 
man halt mal alle zur seriellen Schnittstelle schicken muss. Ein paar 
davon lassen sich kurzzeitig ignorieren, machen aber nach einiger Zeit 
richtig großen Ärger.
Ich würde Nummer zwei erst mal Messtechnisch (Oszilloskop) zu Leibe 
rücken. Eventuell resultiert der Fehler auch aus einer Mischbestückung 
(3,3V oder weniger und 5V). Grundsätzlich sollte man die 
Betriebsspannungen, auch über längere Zeit, im Auge behalten.

von Peter D. (peda)


Lesenswert?

Ja, bei den AVRs hat das I2C hardware Bugs.
Vergleiche mal das original I2C des 80C552 mit dem des ATmega8
http://www.keil.com/dd/docs/datashts/philips/8xc5x2_ov.pdf

Du wirst sehen, von der Programmierung her sehen die exakt gleich aus.
Nur von der Implementierung her leider nicht.
Das I2C des 80C552 läuft wie dumm, die AVRs können hängen bleiben.
Ich hab das leider erleben müssen, da die alten 80C552 nicht mehr 
hergestellt werden. Ich dachte mir, einfach das C-Programm auf den AVR 
portieren, aber das war ein Irrtum.
Erst als ich ein Timeout implementiert hatte, konnte das I2c wieder 
leidlich benutzt werden. Der Timerinterrupt überwacht, ob ein erwarteter 
I2C-Interrupt >1ms ausbleibt und resettet dann das I2C (Disable, 10µs 
Delay, Enable).

Besonders stört das bei Multimaster-I2C:
http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html

von Thomas W. (diddl)


Lesenswert?

Wenn das I2C Display "hängen" bleibt, dann hängt es wahrscheinlich am 
direction register des I2C PIO.

Aus unerfindlichen Gründen scheint es ganz selten einen Reset zu 
kriegen. Das ist die einzige Erklärung für mich, warum auf Ausgang 
geschaltene IO plötzlich Eingang werden.

Jedenfalls hilft es, ab und zu die Direction register neu zu schreiben. 
Seither läuft es bei mir durch, 24x7 seit Monaten.

von Olaf (Gast)


Lesenswert?

> Woher kommen eigentlich solche Störungen?

Fehler bei jeder Art von Datenuebertragung sind normal. Natuerlich 
treten sie bei einer gut designten Hardware nur alle xMonate/Jahre mal 
auf.
Du hast also ein Problem mit deiner Hardware. Sei dankbar und bringe 
erst deine Software auf einen vernuenftigen Stand.
Bei einem FEhler sollte du einfach mal 20-30x mal mit der Clockleitung 
wackeln. Danach das I2C-Interface des Microcontrollers komplett neu 
initialisieren. Und dann verbesserst du deine Hardware!

Es soll aber wohl auch Devices geben die sich weghaengen und dabei die 
Clockleitung auf Low ziehen. Diese Designfehler sorgen dafuer das du 
deine Schaltung komplett resetten musst.

Generel ist I2C daher fuer ernste industrielle Anwendungen die viele 
Jahre 24/7 laufen sollen ziemlicher Murks.

Olaf

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,


danke für die zahlreichen Antworten und die Beschreibungen der an sehr 
unterschiedlichen Stellen vermuteten Fehler. Ich werde mal das neue 
Wissen ins Experiment mit einbeziehen.

Die Leitungslänge kann ich momentan nicht direkt verringern. Beim 
nächsten Aufbau wieder. Die Pullup-Widerstände zu vermindern wäre eine 
Kleinigkeit. Die Idee mit dem Timeout könnte ich noch testen. Neu 
initialisieren... Alle 250ms neu Schreiben dürfte problemlos gehen.

Zumindest habt Ihr mir die Bestätigung geliefert, daß diese Abbrüche 
keine Seltenheit sind. Das Programm konnte schon bis > 10000 zählen und 
die Zahl auf dem GLCD in rasender Schnelle anzeigen.

Bei mir läuft noch eine selbst programmierte Funkuhr mit 
alphanumerischem I2C-Display 24/7. Nach einiger Zeit erscheinen Zeichen 
an falschen Stellen. Beobachtung: Zieht man an der Steckdosenleiste 
daneben einen Stecker kann so ein unerwünschter Fehler entstehen. Ok, 
das popelige 5V-Steckerschaltnetzteil ist selbst schon eine 
Störungsschleuder. Fehlerkorrektur hat das Programm nicht.

Die ganz oben genannte Schaltung lief mit Batterien, aber mit 
angestecktem Programmierstecker zum PC.

Mit freundlichem Gruß

von Wolfgang (Gast)


Lesenswert?

Christian S. schrieb:
> Die ganz oben genannte Schaltung lief mit Batterien, aber mit
> angestecktem Programmierstecker zum PC.

Und wie sah es mit Abblockkondensatoren in deiner Schaltung aus?

von Klaus (Gast)


Lesenswert?

Olaf schrieb:
> Bei einem FEhler sollte du einfach mal 20-30x mal mit der Clockleitung
> wackeln. Danach das I2C-Interface des Microcontrollers komplett neu
> initialisieren.

8 mal reicht, oder solange, bis SDA High geworden ist. Das mache ich 
immer am Anfang der Initialisierung.

Und immer ACK bzw NAK auswerten. Dann bekommt der µC auch mit, wenn was 
im Busch ist.

spess53 schrieb:
>> 2 x 4,7 k zum +
>
> Kann durchaus schon zu hoch sein. Lies mal hier:

Ist hier schon tausend mal diskutiert worden und war nie der Grund.

MfG Klaus

von Christian S. (roehrenvorheizer)


Lesenswert?

Abblockkondensatoren befinden sich an jedem IC.

von Olaf (Gast)


Lesenswert?

> Und immer ACK bzw NAK auswerten. Dann bekommt der µC auch mit, wenn was
> im Busch ist.

Das versteht sich ja wohl von selbst. Wer darauf nicht achtet dem ist 
sowieso nicht zu helfen.

Olaf

von Bernd K. (prof7bit)


Lesenswert?

Zumindest beim Atmega muss man beachten daß dessen I²C Master 
theoretisch imstande ist im Multimaster-Betrieb zu arbeiten, in diesem 
Zusammenhang gibt es einen Zustand "Arbitration lost", wenn der auftritt 
MUSS man ihn gesondert behandeln. Anscheinend ist es nun so daß der 
ziemlich empfindlich reagiert wenn während er gerade am Schreiben ist 
irgend "etwas" (Störung?) an der SDA-Leitung wackelt, er nimmt dann 
sofort beide Hände vom Bus und rührt sich nicht mehr. Man muss penibelst 
genau alle möglichen und unmöglichen Zustände (wirklich alle) aus den 
Statusbits auslesen und jeden geeignet behandeln. Der I²C-master im 
Atmega macht keinen Spaß. Und er versteht auch keinen.

Einfacher und robuster ist es (und schlägt auch mit weniger Code zu 
Buche) wenn man einfach einen Bitbanging-I²C Master zu Fuß 
zusammenklöppelt, so kompliziert ist I²C eigentlich nicht.

von spess53 (Gast)


Lesenswert?

Hi

@Bernd K. (prof7bit)

Ehrlich gesagt so ein wirres Zeug, wie in deinen 'Beitrag', habe ich 
lange nicht gelesen.

Ich benutze i2c auf Atmegas (Atmega128/1281) seit über 14 Jahren auf 
verschiedenen Geräten. Und das problermlos.

MfG Spess

von Bernd K. (prof7bit)


Lesenswert?

spess53 schrieb:
> habe ich
> lange nicht gelesen.
>
> Ich benutze i2c auf Atmegas (Atmega128/1281) seit über 14 Jahren auf
> verschiedenen Geräten. Und das problermlos

Na und, wen interessiert das? Dann musst Du es halt nochmal lesen, 
vielleicht diesmal sinnentnehmend. Ich habe nicht geschrieben daß es mit 
irgendeiner korrekten Treibersoftware nicht problemlos funktionieren 
kann sondern daß bei der Implementation eines neuen Treibers (from 
scratch) wie es der OP anscheinend beabsichtigt bei dieser Hardware 
gewisse Sachen zwingend zu beachten sind die nicht auf den *ersten 
Blick* offensichtlich sind. Und auch nicht auf den zweiten, denn wer 
kommt zum Beispiel auf die Idee Multimaster-Arbitration behandeln zu 
müssen oder daß dieser Zustand überhaupt auftreten kann obwohl er nur 
einen einzigen Master einsetzt?

: Bearbeitet durch User
von roehrenvorheizer (Gast)


Lesenswert?

aha, du meinst wohl das hier (multimasterfähiger ATmega):

Table 22-2. Status codes for master transmitter mode.
0x38 Arbitration lost in SLA+W or data bytes

2-wire Serial Bus will be released and not addressed
Slave mode entered
A START condition will be transmitted when the bus
becomes free

von Bernd K. (prof7bit)


Lesenswert?

roehrenvorheizer schrieb:
> aha, du meinst wohl das hier (multimasterfähiger ATmega):

Genau das meine ich. Du wirst nicht umhinkommen diesen Zustand zu 
behandeln denn er kann auch in Single-Master Umgebungen auftreten. Man 
munkelt sogar von einem Bug in der Hardware (hab aber auf die Schnelle 
keine offiziellen Referenzen dazu). Frag doch mal das Bit ab und setz 
einen Breakpoint (oder lass ne LED blinken falls kein Debugger zur Hand) 
und warte ob es auftritt.

von roehrenvorheizer (Gast)


Lesenswert?

> Frag doch mal das Bit ab
> und warte ob es auftritt.

Ich bin auf dem Weg....   kann aber noch dauern.

von Christian M. (Gast)


Lesenswert?

Olaf schrieb:
> Es soll aber wohl auch Devices geben die sich weghaengen und dabei die
> Clockleitung auf Low ziehen.

Echt, ich kenn nur dass Data hängenbleibt, dann geht das mit 8mal 
wackeln am Clock. Dafür gibt's sogar ne AN. Wen's interessiert, liefere 
ich Link noch nach, bin grad mobil.

Dass der Clock hängen bleibt muss ja mit dem Clock-Stretching 
zusammenhängen, sonst macht ja der Slave nichts am Clock.

Gruss Chregu

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Ich benutze i2c auf Atmegas (Atmega128/1281) seit über 14 Jahren auf
> verschiedenen Geräten. Und das problermlos.

Daß etwas funktioniert, ist noch lange kein Beweis der Bugfreiheit.
Es hängt davon ab, ob die I2C-Leitungen die Platine verlassen und 
Störungen einfangen können.
Im besten Fall geht er nur in die Arbitration lost States, aber er kann 
sich auch komplett verriegeln, wo er nur mit einem Disable wieder 
rauskommt.

Als ich mit I2C auf den Philips-8051 angefangen habe, habe ich als 
Härtetest während I2C-Traffic mit Teststrippen SDA/SCL gegen GND 
gezogen. Die Philips habe dann auch brav Fehler erkannt, aber sind immer 
von selber wieder heraus gekommen. Ein Disable oder Timeout war nicht 
nötig.

von spess53 (Gast)


Lesenswert?

Hi

> Ich habe nicht geschrieben daß es mit
>irgendeiner korrekten Treibersoftware nicht problemlos funktionieren
>kann sondern daß bei der Implementation eines neuen Treibers (from
>scratch) wie es der OP anscheinend beabsichtigt bei dieser Hardware
>gewisse Sachen zwingend zu beachten sind die nicht auf den *ersten
>Blick* offensichtlich sind.

Ich rede auch nicht von irgendeiner Treibersoftware sondern von 
selbsgeschriebener Software.

Das Ganze ist durchaus nicht die Raketentechnik, die du daraus machst. 
In den meisten Fällen reicht das 'sinnentnehmende' Lesen des Datenblatts 
und das Verständnis wie I²C so tickt.

MfG Spess

von Joachim B. (jar)


Lesenswert?

Olaf schrieb:
> Es soll aber wohl auch Devices geben die sich weghaengen und dabei die
> Clockleitung auf Low ziehen. Diese Designfehler sorgen dafuer das du
> deine Schaltung komplett resetten musst.

schrieb ich schon:

Joachim B. schrieb:
> das I2C am AVR nicht mit clock stretching zusammengeht,
> da könnte man mit einem anderen Port warten ob SCL wieder high geht.

das hier war mir neu, könnte man mit Timeout für SCL prüfen am AVR ja 
einbauen

Christian M. schrieb:
> dann geht das mit 8mal
> wackeln am Clock. Dafür gibt's sogar ne AN. Wen's interessiert, liefere
> ich Link noch nach, bin grad mobil.

aber ich denke warten bis SCL wieder hochgeht müsste reichen.

von Peter D. (peda)


Lesenswert?

Joachim B. schrieb:
> aber ich denke warten bis SCL wieder hochgeht müsste reichen.

Darum geht es nicht. Angenommen Du machst ein Reset während ein PCF8574 
gerade gelesen wird, dessen 8 Eingänge auf low liegen, d.h. der zieht 
SDA 8 SCL-Takte lang auf low.

von Joachim B. (jar)


Lesenswert?

Peter D. schrieb:
> Joachim B. schrieb:
>> aber ich denke warten bis SCL wieder hochgeht müsste reichen.
>
> Darum geht es nicht. Angenommen Du machst ein Reset während ein PCF8574
> gerade gelesen wird, dessen 8 Eingänge auf low liegen, d.h. der zieht
> SDA 8 SCL-Takte lang auf low.

ich sehe grad das "Problem" nicht, wer soll denn nun abstürzen?
der PCF8574 oder der Atmel?

Wenn ich feststellen würde der PCF8574 hängt sich auf (was ich noch NIE 
sah) würde ich den PCF8574 resetten, d.h. den seine VCC an einen Atmel 
Port hängen und toggeln dann sollte der PCF8574 wieder resettet sein.

von Christian M. (Gast)


Lesenswert?

Ich habs damals ähnlich
http://www.analog.com/media/en/technical-documentation/application-notes/54305147357414AN686_0.pdf
gemacht. Solution 1: Clock dich durch's Problem :-))
Dafür hab ich den Bus manuell übernommen, SDA auf high, 8mal geclockt, 
fetich!

Hier noch mein Code, für PIC16F678 und MikroBASIC:
1
sub function alt_i2c_reset(dim daten as byte) as byte 'I2C Bus resetten
2
  dim anzahl_bits as byte
3
  Delay_us(800)
4
  ClearBit(SSPCON, SSPEN)
5
  ClearBit(PORTC, 3)
6
  for anzahl_bits = 1 to 9
7
    Delay_us(100)
8
    ClearBit(TRISC, 3)
9
    Delay_us(100)
10
    SetBit(TRISC, 3)
11
  next anzahl_bits
12
  SetBit(SSPCON, SSPEN)
13
  Delay_us(800)
14
  result = 0
15
end sub

Sehe grad, die i2c_wr, _read und_ack habe ich auch ersetzt, weil in 
denen bleibt er dann hängen!
Mit dieser Brachial-Methode läuft nun mein Bus problemlos schon mit mehr 
als 2 Milliarden Zugriffen ohne Unterbruch!

Gruss Chregu

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.