Hallo allerseits, ich habe eine Schaltung, in der ein Tiny44 mit einem I2C-Display verbunden ist. Der µc läuft mit 5V und das Display mit 3,3V. Es funktioniert ohne TWI oder USI, sondern nur über direkt gesteuerte Pins. Auf das Display läßt sich schreiben wie erwartet. Bisher sollte nur geschrieben werden, ohne auf das ACK-Bit zu achten, das das Display als Antwort zurück gibt. Neuerdings möchte ich das ACK-Bit auswerten können, um erkennen zu können, wenn z.B. das Display nicht antwortet. Was ich gemacht habe: Ich habe eine kurze Programmschleife erstellt, die nach dem Initialisieren des Displays nur noch "die Adresse und Scrolle zwei Zeilen nach unten" angibt, dann kurz wartet. Das Display zeigt den Text eben um zwei Zeilen verschoben an. Somit lassen sich die zwei zu übertragenen Bytes samt ACK-Bit auf dem Oszilloskop darstellen. Bei falscher Adresse erscheinen keine ACK-Bits, also ACK bleibt high, bei korrekter Adresse erscheint nach beiden Bytes ACK = 0 low. Nur gelingt es mir trotz aller Versuche nicht, das ACK-Bit im Programm zu erkennen. Es ist immer 0. Warum nur? Liegt es am Pegel oder doch am Programm? Vielleicht kann mir bitte jemand auf die Sprünge helfen, wo mein Denkfehler liegt oder mir zeigen, wie das richtig geht. Im Anhang findet sich eine gekürzte compilierbare Programmmversion, die im Wesentlichen die direkte I2C-Übertragung zeigt. Das Unterprogramm "GetAck" wird immer am Ende der Übertragung eines Bytes aufgerufen. Es soll des SDA-Pin auf Eingang umschalten und den Zustand dieses einen Pins einlesen, sowie SCL weiter schalten. Vielen Dank schonmal. mit freundlichem Gruß
Christian S. schrieb: > das ACK-Bit im Programm zu erkennen. Es ist immer 0. Was meinst Du mit "0"? Es soll doch low (0) sein, oder? Übrigens sehe ich nicht ganz, wie Du das Clock-Stretching realisierst. Sollte hier aber jetzt keine Problem sein.
Falls die Adresse falsch ist, soll es aber 1 sein. MfG
Christian S. schrieb: > Falls die Adresse falsch ist, soll es aber 1 sein. Deine Routinen benutzen "WaitHalfCycle()", welche (mit Aufruf) 17 Taktzyklen braucht. 17 Taktzyklen sind bei 8MHz 2.25us. Mal 2 ergibt 4.5us. Ergibt 222KHz. Bei 4MHz sind es immer noch 111KHz. Selbst mit Pinumschalten dazwischen ist das sehr knapp. Aber egal. Solange du nur schreibst gibt es auf SDA definierte Zustände, entweder LOW oder HIGH. Wenn du aber lesen willst, brauchst du PullUp auf SDA, entweder direkt am I2C Bus oder internen PullUp von Tiny. Und ich sehe nicht, dass bei dir etwas eingeschaltet wird. Falls das Display keine Pullup Widerstände hat, geht so etwas mit sehr hoher Wahrscheinlichkeit in die Hose, weil bei NACK der BUS nur HiZ (Potentialfrei) ist und das ist bei 3V3 auf 5V wahrscheinlich nicht gut genug.
Es sind Pullup-Widerstände 2,2k zu +3,3V eingebaut. MfG
Hallo, I2C ist ein Bus, der High nur von den PullUp-Widerständen bekommt und bei dem nur aktiv Low gesteuert wird. Insofern ist der Ansatz, hart ein H anzulegen, ohnehin riskant. Ein Slave kann prinzipiell jederzeit SDA oder SCL auf Low ziehen (Clock Stretching wurde ja schon genannt), dann wird ein auf H befindlicher Ausgang des AVR vom Slave auf L gezogen... Das ist mehr oder weniher ein Kurzschluß und nicht so gesund für die Hardware. Üblicherweise wird der SDA und SCL als Ausgang/Low für Low oder als Eingang als High gesetzt. Es wird also über das DDR gesteuert. Damit gibt es auch keine Konflikte beim Einlesen, wenn SDA/SCL vom AVR auf "High" gesetzt sind, sind sie ohnehin Eingang und können jederzeit gelesen werden. Also SDA/SCL auf per DDR Eingang und Output auf Low ist Ruhepegel High durch externem PullUp. Für Low jetzt nur DDR aus Ausgang und dann wieder auf Eingang. Gruß aus Berlin Michael
Hallo, danke für die Antworten. Im Prinzip wollte ich es ja so verwirklichen, wie Du erklärt hast. Ganz oben in meinem Programm steht: "Achtung!!! Damit das Display niemals über 4 Volt abbekommt, dürfen die I2C-Ausgänge NIEMALS hart gegen + schalten, sondern müssen immer nur gegen GND schalten und für high auf hochohmig geschaltet werden." Ich denke, das war von vornherein klar. Mit freundlichem Gruß
Hallo, war vielleicht schon jemand mit einem solchen Fall konfrontiert? MfG
vielleicht helfen dir meine bitbang-i2c-routinen weiter. Müsste eigentlich das gleiche Problem sein. Funktioniert einwandfrei. Beitrag "Re: stm32f103 i2c_read"
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.