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ß
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
Man schreibt doch sowieso mit dem Timer auf den Display. Und dann schreibt man immer ohne Warten. So kann nichts haengenbleiben.
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.
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
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.
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
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.
> 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
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ß
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?
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
> 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
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.
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
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
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
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.
> Frag doch mal das Bit ab > und warte ob es auftritt. Ich bin auf dem Weg.... kann aber noch dauern.
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
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.
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
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.