Hallo Leute,
ich habe ein Bild im Anhang mit einem aufgenommen I2C-Signal.
Dort wird die Slaveadresse 0x70 übergeben was man auch gut in den
ersten 8 Takten erkennen kann (ich habe Zahlen drüber geschrieben)
nun ist der 9. Takt ja zur Bestätigung zuständig. Der Slave gibt ein
ACK raus in dem er die SDA Leitung auf LOW zieht, passiert ja in diesem
Fall auch, mit der fallenden Taktflanke von dem 9. Takt von SCL wird die
SDA Leitung auf LOW gezogen, doch was soll der Anstieg davor bedeutetn?
Es sollen doch nur NULLEN übertragen werden.
Weiß vielleicht jemand einen Rat?
Vielen Dank schonmal!
Das schaut sich an wie signale die zu schnell gesended werden oder keine
gute pull-ups oder lange leitung. Stimmt das das ich da 10 MS/s siehe ?
Der 'Anstieg' habe ich oefter gesehen, der Master zieht das signal
wahrscheinlich besser tief als der slave.
Ich glaube, Deine Interpretation des Screenshots ist nicht völlig
zutreffend:
Der Master läßt nach erfolgter Übertragung des achten Bits - d.h. kurz
nach der fallenden Flanke des achten Taktimpulses auf SCK - SDA los,
damit der adressierte Slave sie gegebenenfalls nach Low ziehen kann. Das
tut er auch, nur zieht er quasi "nicht ganz so kräftig" wie der Master
(oder der Spannungsabfall der Leitung zwischen beiden ist nicht
vernächlässigbar und die Messung fand direkt am Master statt), so daß
der Pegel etwas höher bleibt. Der Slave hält sein Acknowledge so lange,
bis er die fallende Flanke des neunten Taktimpulses erkennt. Dann läßt
er SDA los, und der Pegel will gen VCC schnellen (das ist die schmale
Nadel am Ende des ACK), doch der Master übernimmt SDA sofort wieder für
die Übertragung des nächsten Bytes.
Im Grunde sieht also alles okay aus.
Hätte auch gesagt das sieht sehr "Kapazitiv" aus.
Was für Pullups hast Du drin?
Können Deine Teilnehmer die Kapazitäten in den geforderten Zeiten
treiben?
der Gast schrieb:> Der Slave gibt ein> ACK raus in dem er die SDA Leitung auf LOW zieht, passiert ja in diesem> Fall auch, mit der fallenden Taktflanke von dem 9. Takt von SCL wird die> SDA Leitung auf LOW gezogen, doch was soll der Anstieg davor bedeutetn?
Dein Slave schafft es nicht, SDA richtig auf low zu ziehen (obwohl der
Pegel reichen könnte). Gibt es einen Angst(Längs)widerstand in der SDA
Leitung?
Tach schrieb:> Hätte auch gesagt das sieht sehr "Kapazitiv" aus.
Dazu sind fallende und steigende Flanken zu steil, es ist etwas
"Ohmisches"
MfG Klaus
Klaus schrieb:> Tach schrieb:>> Hätte auch gesagt das sieht sehr "Kapazitiv" aus.>> Dazu sind fallende und steigende Flanken zu steil, es ist etwas> "Ohmisches"
Kann auch der Tastkopf sein.
Aber beim "laden" der Leitung hat es deutlich 1-e Charakter.
Das sieht in meinen Augen halt so aus, als ob die Teilnehmer zwar
schnell genug entladen, aber die Aufladung durch den Pullup begrenzt
wird.
also ich hab 4.7k Widerstände und eine LEitungslänge von unter 30cm.
Ich weiß halt nicht wie der Slave reagiert, da ich ein Display ansteure,
welches aber nichts ausgibt, doch anhand des ACK erkenn ich doch, dass
das Display dem Master antwortet?! Seh ich das richtig??
Patrick C. schrieb:> Auf welche bus-frequenz arbeitest du ?
Wenn es zu schnell wäre, würde das Signal nicht High werden, hier ist
das nicht erreichte Low das Problem. Daß der Slave reagiert sieht man,
sonst würde man das "versuchte" Low, das ACK, nicht sehen (SDA würde
einfach auf High gehen). Man sieht an der Nadel deutlich, daß der Slave
den Bus mit der fallenden Flanke von SCL freigibt und dann der Master
wieder SDA treibt.
Ich wette immer noch auf einen Längswiderstand oder ein Problem in der
Versorgung des Slaves, so daß der Slave-Treiber die 1mA, die man bei
4,7kOhm braucht, nicht nach GND ziehen kann.
MfG Klaus
@Klaus, was genau meinst du mit Längswiderstand? Sowas wie ein
Leitungswiderstand, also in Reihe mit der Leitung?
Du sagtest es könnte auch an der Versorgung des Slaves liegen,
da liegt auch mein Problem, ich hab zu dem Display kein Datenblatt,
es ist ein Chip on Glass Display und zu dem Chip hab ich aber ein
Datenblatt,
aus diesem Datenblatt hab ich die Versorgungsspannungen Vcc und Vlcd
genommen, kann da vielleicht ein Fehler sein?
der Gast schrieb:> doch anhand des ACK erkenn ich doch, dass> das Display dem Master antwortet?! Seh ich das richtig??
Richtig. Bisher kann man davon ausgehen das es kein Problem gibt und
alles (Auf I2C Ebene) so läuft wie es soll.
Hallo,
bist Du sicher, dass das, was Du für einen "Takt" interpretierst auch
den definierten Setup- und Hold-Zeiten entspricht?
Diese Taktnadeln generieren aus meiner Sicht "per Zufall" ein
Datensignal.
Ich würde zuerst einmal versuchen einen sauberen Takt zu generieren. Als
erstes einmal Anfangen, den Pull-Up zu verkleinern (versuch einen 1k8),
dann evtl. die Übertragungszeit vergrößern. Und am Besten noch mal ein
Oszi-Bild mit den passenden Skalen zum Signal (so ist das eher ein
Schätzdiagramm, aus dem man NICHTS ableiten kann).
Gruß
TK
HIer mal das Bild mit 1,8k Pull-Up Widerständen.
Das Datensignal wird nicht per Zufall definiert,
das sind genau die Daten die ich im Programm definiert
hab, habe mein Code auch mal angehangen!
Das Blinken der LED hat keine bewandtnis sondern soll nur
die Funktuion anzeigen!
In dem Bild kann man schön erkennen dass das erst was übertragen wird
die Adresse ist 70hex -> 01110000 dies geschieht in den ersten 8 (9)
Takten,
in den nächsten 8 (9) Takten soll laut Programm 11001000 übertragen
werden, was man auch wieder im Oszillogram erkennt.
Somit kann wohl ausgeschlossen werden, dass zufällig Daten generiert
werden!
Das sieht für mich wie ein Kurzschluß aus:
Der Master treibt ein starkes High (was er nicht darf) und der Slave
treibt ein starkes Low (was er darf).
Daraus ergibt sich ein Pegel von irgendwo zwischen High und Low, und die
Bauteile leiden.
Der I2C-Bus arbeitet mit Open-Collector, d.h. ein Teilnehmer darf
entweder ein starkes Low anlegen oder er muß die Leitung "loslassen".
Der Teilnehmer darf aber nie eine starkes High anlegen.
Check Deine I2C-Implementierung im µC.
High wird erzeugt, indem man den Portpin im DDR auf "Eingang" schaltet.
Das eigentliche High erzeugt dann der Pullup.
> Das sieht für mich wie ein Kurzschluß aus
Nö. Er hat halt nur die Pullups auf 1k8 verkleinert, aber der Slave -
der vorher schon mit 4k7 Probleme hatte mit den Strom fürs Low - kann
die nicht sauber auf 0 ziehen, weil der SDA Ausgang zu schlapp ist.
Dass der Master nicht auf Push-Pull steht sieht man nur im obersten
Bild, im unteren kaum noch.
Ich würde eher empfehlen die Pullups auf 10k zu erhöhen und etwas mit
der Busgeschwindigkeit herunter zu gehen. Aber die Pegel sahen bei 4k7
soo schlecht eigentlich nicht aus - leider kann man die Spannung nicht
wirklich ablesen.
Erhöhter Übergangswiderstand durch schlechten Kontakt hätte übrigens
dasselbe Fehlerbild.
Sebastian W. schrieb:> Der Slave zieht aber noch genug runter. Der Master erkennt es ja as Low> und macht weiter. Ist doch also alles gut, oder?
Die Frage ist:
Warum zieht der Slave nicht auf 0V runter? Ist er vielleicht beschädigt?
4,7k ist ja nichts besonders...
Also zuerstmal kann man sehen, dass die Form von SDA und SCL bei 1k8
Pull-Ups dem entspricht, was ich jetzt auch als "vernünftige" Flanken
ansehen würde. Je größer die Pull-Ups werden, desto mehr e-Fkt entsteht
aufgrund von Kapazitäten in den Stichleitungen, in den Verdrahtungen des
Steckboards, aufgrund von Eingangskapas von Master / Slave - Pins. Daher
sollten die Pull-Ups NICHT mehr vergrößert werden. Wenn ich mir das
zweite Bild ansehe, kann man jetzt jedoch erkennen, dass das ACK-Bit vom
SLAVE "nur" noch auf ca. 2V für einen L-Pegel runtergezogen wird. Im
ersten Bild lag der L-Pegel noch bei ca. 1V (geschätzt). Dies läßt die
Vermutung aufkommen, dass in den SDA-Leitungen/Stichleitungen - wie
einer der Vorredner schon mal anmerkte - irgend eine Art von
Serienwiderständen existiert (vermutlich Größenordnung von 1k2 - nur
dann würde der Spannungsteiler 1k8 zu 1k2 mit ca. 3V/2V hinkommen und
aus dem ersten Bild mit den 4k7 zu 1k2 = 4V/1V!). Da ich jetzt nicht
davon ausgehe, dass eine Verdrahtungsleitung auf deinem Steckboard mit
1k2 anzusetzen ist, muss da eben was anderes sein.
Weiterhin solltest Du Dir auch mal die Spec vom IIC ansehen, um zu
verstehen, wie der angesteuert werden muss - eben nicht mit einem
AUSGANG H und einem AUSGANG L, sondern mit einem INPUT (=H) und einem
AUSGANG L.
Und bitte kein Kommentar, dass man EEPROMS doch auch mit AUSGANG H/L
ansteuern kann - JA das geht aber nur solange, bis ein Device sich an
die Spec hält - dann geht das eben nicht mehr!
Gruß
TK
TK schrieb:> Weiterhin solltest Du Dir auch mal die Spec vom IIC ansehen, um zu> verstehen, wie der angesteuert werden muss - eben nicht mit einem> AUSGANG H und einem AUSGANG L, sondern mit einem INPUT (=H) und einem> AUSGANG L.
Tut er ja offensichtlich. Oder wie kommst du darauf das er das nicht so
macht?
Wenn der Thread-Starter in der Zwischenzeit keine Pinkonfigurationen
verändert hat, kann man in der ersten Aufnahme sehen, dass alle Bus-
teilnehmer in Open-Drain-Konfiguration arbeiten:
Es wird aktiv gegen GND gezogen und nicht mehr gegen die PullUp
-Spannung. Daher kommen die verschliffenen Signale (Ladekurve
der Buskapazität).
In der ersten Aufnahme sieht man, dass das bei jeder Flanke so ist.
Die Signale sind aber mit 4k7 PullUp sehr verschliffen ("Haifisch-
flossen". Es wird ja noch nicht einmal die PullUp-Spannung
beim Clock-Signal erreicht.).
Die I2C-Spezifikation rät hier sowieso zu PullUp
-Widerständen im Bereich unter 2k. Je nach PullUp-Spannung variiert
das noch, damit man einen garantierten Minimalstrom und dadurch
eine gewisse Störunempfindlichkeit hat.
Nachdem der Tread-Starter die beiden PullUp-Widerstände gegen 1k8
getauscht hatte, sehen beide Signale jetzt so aus, wie man sich
das auch vorstellt.
Die "komischen" Pegel und Ausreißer kann man jetzt auch besser erkennen.
Der Pegel, der nicht richtig auf GND liegt, sieht tatsächlich so
aus, als wenn hier die Serienwiderstände (die laut I2C-Spezifikation
standardmäßig bei 100 Ohm liegen sollten) viel zu groß wären.
Der Thread-Starter sollte mal seinen Schaltplan mit allen
Bus-Teilnehmern
und am besten noch mit den jeweiligen Versorgungsspannungen zeigen.
Die Serienwiderstände würde ich immer vorsehen:
1.: Weil sie die I2C-Spezifikation vorschreibt.
2.: Weil man dadurch wenigstens ein Minimalmaß an Schutz gegenüber
Spannungspeaks auf den Busleitungen erhält (I2C-Spezifikation spricht
hier von "High energy spikes".).
3.: Weil man auch gerade in Debug-Phasen sich den Luxus erlauben
kann, die Serienwiderstände mit unterschiedlichen Werten zu bestücken.
Dann kann man sehr schön sehen, wer gerade am Bus zieht - durch die
unterschiedlichen GND-Shifts.
Ich habe außerdem noch mal die "Haifischflosse" durchgerechnet:
-> f_clk = 100kHz (Pulsbreite daher 5µs)
-> ca. 90% des PullUp-Pegels wird erreicht
-> r_pullup = 4k7
Ich komme da auf ~462pF Buskapazität (zumindest an der Clock-Leitung).
Die I2C-Spezifikation erlaubt maximal 400pF. Und das ist auch nur
schwer zu erreichen. Jeder Busteilnehmer darf maximal 10pF an
seinem Pin erzeugen. Der Rest muss dann der Bus sein:
462pF - 2x 10pF = 442pF ??
Ich habe so eine Konstellation schon einmal gesehen. Da war der Bus
aber 70cm lang und über 5 (!) Platinen verteilt über Flachbandkabel
miteinander verbunden usw. Sowas scheint der Thread-Starter aber
nicht zu haben.
Trotzdem muss aber diese sehr hohe Buskapazität irgendwo her
kommen.
Na weil ein ACK/NACK-Bit mit L(=2V) definitiv NICHT als L erkannt werden
darf. "L-Level Input Voltage (Standard Mode) -> 0.3Vdd".
Gut, die 2V auf dem 2. Bild sind von mir geschätzt, aber besser kann man
das dort nicht ablesen. Und wenn die Spec hier schon nicht eingehalten
wird, dann gibt es ein Problem in der Ansteuerung/Auswertung.
Da ich die i2cmaster-Library nicht kenne, habe ich mir die jetzt mal
kurz angesehen. Und OK- ich gebe zu, die Ansteuerung dort ist im Großen
und Ganzen in ordnung. Aber dann sollte man auch nach jedem i2c_write()
auch den Returnwert abfragen, denn dort steht das ACK-Bit drin. Und noch
was als Anmerkung zur Library: Die Abfrage zum Clk-Stretching geht nur
dann gut, wenn man keinen Watch-Dog aktiviert hat, denn es gibt z.B.
(Druck-)Sensoren, die benötigen im worst-case bis zu 1s für eine int.
Wandlung und halten in dieser Zeit den SCL auf L. Das würde mit der
Library nicht mehr ohne weiteres funktionieren.
Gruß
TK
Und gavgva43 unterstreicht mit seinem Beitrag auch noch mal das, was ich
vorher angemerkt habe:
- Lest euch die Spec durch, dann können schon mal Fehlerquellen im
Vorfeld ausgeschaltet werden. Hier z.B. die Kombi zwischen Pull-Ups (Rp)
und Serienwiderständen (Rs). Da gibt es mehrere, schöne Diagramme,
welche die Abhängigkeit aufzeigen und das sogar auch noch in Abh. der
Versorgungsspannung. Dann ist eine Kombi Rp=4k7 und Rs=1k2 bei Vdd=5V
eben nicht mehr zulässig! (Ich habe jetzt hier unterstellt, dass es
einen Rs in dieser Größenordnung gibt.)
Da aber jeder, der mit IIC arbeitet und der dann irgendwelche Probleme
hat (davon gibt es hier im Forum ja genügend) entweder auf:
1) eine Library zurückgreift, die er nicht selbst programmiert und damit
verstanden hat (das ist jetzt mal eine Unterstellung!)
2) eine Hardware kreiert, die "andere" auch schon mal benutzt haben und
die dann in einer speziellen Konstellation nicht mehr funktioniert.
Und um allen Spekulationen ein Ende zu bereiten sollte der TO mal seinen
Schaltplan anhängen. Weil das Schätzen von Werten anhand von 2
Oszi-Bildern zwar möglich aber in dem Zusammenhang nicht hilfreich ist.
Gruß
TK
gavgva43 schrieb:> Die Serienwiderstände würde ich immer vorsehen:> 1.: Weil sie die I2C-Spezifikation vorschreibt.
Interessanter Beitrag, und der Trick mit den verschiedenen Werten ist
echt gut. Allerdings meine ich, das die I2C-Spezifikation die
Serienwiderstände nur empfiehlt, aber nicht vorschreibt (z.B. 7.2:
"Series resistors Rs are optional").
LG, Sebastian
Ja.
Erzähl mal einem Kunden bei einem Fehler später,
dass Du nicht alle Empfehlungen umgesetzt hast.
Ich gebe Dir Recht, dass die Serienwiderstände
"recommended" sind, bin aber auch der Meinung,
dass man hier kein Geld sparen sollte.
Vor allem, weil sie einen tatsächlichen Nutzen
haben.
Ich schilder ein weiteres Problem,
wie man sieht hat das Display 6 anschlüsse, davon ein NC,
ich weiß dass das Display mit dem Controller PCA85133 arbeitet,
zu dem COntroller hab ich ein Datenblatt, zu dem Display fehlen mir
sonst
jegliche Informationen. Ich weiß halt auch nicht mit welchen Spannungen
ich
das Display versorgen muss, ich hab laut DAtenblatt (Anhang S. 30)
Vlcd auf 7V und Vdd auf 5V eingestellt, kann ich so vorgehen?
Vielen Dank für die Hilfe!!
also ist SDA "WÄHREND" des 9. Takts auf LOW als ACK?!
Seh ich das richtig???
Also ist es in meinem Fall, wenn SDA erst mit der
fallenden Taktflanke des 9. Takts LOW wird kein ACK??
Hallo "der Gast",
das ACK wird in dem Fall vom SLAVE-Device (=LCD) NACH der fallenden
Flanke des 8.Clk ausgegeben (SDA wird auf L gezogen oder eben nicht).
Mit dem 9. Clk wird das ACK dann vom MASTER-Device "verarbeitet" (der
SDA-Pegel wird mit der steigenden SCL-Flanke eingelesen). Sofern die
Setup- und Hold-Zeiten eingehalten werden (je ca. 5us für H- und L-
Anteil eines SCL-Impulses) ist die Kommunikation "im grünen Bereich".
SDA-Pegel dürfen sich (außer bei START und STOP) nur bei SCL=L Pegel
verändern.
Gruß
TK
Okay, vielen Dank dafür schonmal,
ich habe meine Schaltung gründlichst überprüft nach Längs- bzw.
Serienwiderständen, alles im grünen Bereich, ich kann mir nicht erklären
warum der Slave das ACK nicht auf LOW-Pegel gezogen bekommt!
Die I2C-Spezifikation schreibt 3mA vor, die jeder Teilnehmer schaffen
muß.
Bei 1,8k muß also das ACK sicheres Low (<0,4V) sein.
Bleibt also nur, Du hast GND nicht angeschlossen und der Slave versorgt
sich parasitär über Substratdioden aus anderen Pins.
der Gast schrieb:> Was dort aber nicht wirklich beschrieben ist!!
Doch. Da steht doch eindeutig, daß der Ausgang kein normaler SDA ist.
Sondern aufgrund der Herstellungstechnologie des Substrates keine großen
Ströme liefern kann. Daher hat das Teil einen zweiten Ausgang, der einen
externen Treiber ansteuern könnte.
Naja, so versteh ich das zumindest.
@ Abdul, Recht hast du,
aber da es sich bei diesem Display um ein COG (Chip on Glass Display)
handelt hab ich nur die vorhandenen Ausgänge zur verfügung!
Hast du schon eine niedrigere Taktrate versucht? Bzw. kannst du kannst
du kleine Delays zwischen den einzelnen Blöcken einfügen?
Adresse Delay Daten Delay etc.
der Gast schrieb:> @ Abdul, Recht hast du,> aber da es sich bei diesem Display um ein COG (Chip on Glass Display)> handelt hab ich nur die vorhandenen Ausgänge zur verfügung!
Ja und? Pullup am SDA hochohmiger machen und daher langsamster Betrieb,
oder ACK einfach nicht auswerten und auf das Display blind schreiben.
Abdul K. schrieb:> Ja und? Pullup am SDA hochohmiger machen
Warum?
Wenn das Datenblatt nicht eingehalten wird, liegt eindeutig ein
Schaltungsfehler oder ein Defekt vor.
Man bekämpft nicht die Wirkung, sondern man beseitigt den Fehler.
Wir sind doch schließlich keine Politiker.
Peter Dannegger schrieb:> Abdul K. schrieb:>> Ja und? Pullup am SDA hochohmiger machen>> Warum?>> Wenn das Datenblatt nicht eingehalten wird, liegt eindeutig ein> Schaltungsfehler oder ein Defekt vor.>
Oder ein Verständnisproblem.
> Man bekämpft nicht die Wirkung, sondern man beseitigt den Fehler.> Wir sind doch schließlich keine Politiker.
;-)
Naja, ich las es so, daß der Chip zwar normal treibt, aber dieses COG
hochohmige Leitungen bringt. Die haben das vorhergesehen und die Lösung
mit einem extra SDA-AUSgang gemacht. Habe sowas schonmal irgendwo
gesehen.
Abdul K. schrieb:> Die haben das vorhergesehen und die Lösung> mit einem extra SDA-AUSgang gemacht.
SDA-in und -out sind nur auf dem Chip getrennt.
Auf dem Glas müssen sie aber verbunden sein, sonst käme ja gar kein ACK.
Und 1V Abfall bei 4,7k Pullup sind etwa 1k. Sollten die Leiterbahnen
wirklich so hochohmig sein?
Ich find den Thread langsam langweilig. Vermutlich haben die, die beiden
SDA-Pins direkt am Chip verbunden und das nun Doppelsignal über die
hochohmige Bahn des COG nach außen geführt. Gedacht ist es vom
Chiphersteller aber, daß der nach außen treibende SDA-Pin auf der
PLATINE einen o.C.-Buffer auf die andere SDA-Leitung bekommt. Dann würde
es einwandfrei funzen!
Ein Foto würde das klären. Aber wozu, laß die Experten doch kostenfrei
rätseln.
EOT
Versuche es mit blind Schreiben und dann melde dich wieder. Müßig zu
erwähnen, daß du dafür eventuell nicht eine fertige i2c-Lib nehmen
kannst.
Für die blinde Betriebsart spricht auch, daß es offensichtlich kein
Clock-Stretching gibt, der Chip also auf jeden Fall schnell genug ist,
daß man von einem impliziten ACK ausgehen kann. Allerdings schaue ich
deswegen nicht nochmals ins DB.
Viel Spaß!
Wenn Du HW-I2C nimmst, hast Du keine Chance ohne ACK. Bei NACK geht das
HW-I2C automatisch in den nichtadressierten Zustand.
Die 1V sollte ein AVR aber noch als Low ansehen, notfalls den Pullup auf
10k erhöhen und die Baudrate verringern.
Daß die Leiterbahnen 1k hochohmig sind, finde ich sehr erstaunlich. Ist
das LCD gekauft oder aus der Ausschußkiste?
Könnte man ausmessen, indem man die Schutzdioden ausnutzt. Ist
allerdings riskant. Kommt mir auch erstaunlich hochohmig vor. Hätte eher
an 10-100 Ohm gedacht. Der Controller muß ja auch Betriebsstrom
bekommen! Sind diese Leiterbahnen erkennbar wesentlich breiter?
lol Das Barcodes normiert sind und Handys erfunden, ist dir entgangen?
Das Display scheint auch ein Mädchen zu sein. Mal ne Frage: Du kannst
auf diesem Bild die Leiterbahnen sehen? Oder war das ein Multipage-TIFF,
dann entschuldige ich mich.
Gibt es denn jetzt endlich ein Problem bei der I2C Kommunikation, oder
funktioniert immer noch alles?
Ansonsten schlage ich vor den Pull-Up auf 100k zu erhöhen, damit
wirklich mal ein Fehler auftritt und der Thread seine Berechtigung
bekommt :)
Hast du ein anderes I2C Bauteil (Temperatursensor, EEPROM). Schalte es
mit in den Bus und spreche es an, funktioniert es, funktioniert dein Bus
und die Stromversorgung des Panels wird fehlerhaft sein.
Zusatz:
Du hast keinen Plan wie du das Display anschließt, oder?
Es hat 6 Pins, ist ein COG, hiert ist was ähnliches:
http://www.lcd-module.de/pdf/doma/t123-i2c.pdf
Versuche vielleicht einmal deren Verschaltung, Seite 11, Single Supply.
eigentlich dachte ich ich hätte einen Plan,
die Pins sind ja eindeutig beschrieben mit
SCL
SDA
Vdd
Vlcd
GND
NC
aber irgendwie wills doch nicht funktionieren, auch wenn nur die
Spannung anliegt ohne I2C-Signal sollte doch vielleicht schonmal was zu
sehen sein?!
der Gast schrieb:> aber irgendwie wills doch nicht funktionieren, auch wenn nur die> Spannung anliegt ohne I2C-Signal sollte doch vielleicht schonmal was zu> sehen sein?!
eigentlich nicht, nein, der RAM des Displays wird sehr wahrscheinlich
leer sein und Display deaktiviert (siehe 7.12 im Datenblatt)
Und wenn du das Display falsch angeschlossen hast, dann stimmt der
Kontrast nicht und es zeigt dir auch nichts an.
Hast du mal zwischen VDD und VLCD den Kondensator gesetzt. V0 wirst du
nicht haben.
Ich selbst habe das EAT123A-I2C in einer +5V Schaltung so betrieben wie
im Anhang. Frag mich nicht mehr warum ich die Dioden rein gesetzt habe,
denke aber mich daran zu erinnern, dass dadurch der Kontrast geändert
wurde.
Vielleicht funktioniert es bei dir so auch, jedoch musst du es natürlich
davor auch richtig initialisieren und etwas ausgeben bzw. blinken lassen
(siehe Datenblatt deines ICs für den Befehl)
Ich habe mir mal deinen Code angeschaut, ich verwende zwar keine AVRs,
aber ich benutze den I2C-Bus anders. Bei mir besteht ein Schreibbefehl
aus dieser Abfolge:
1
I2C_start();
2
I2C_send_byte(addr);
3
I2C_send_byte(subaddr);
4
I2C_send_byte(value);
5
I2C_stop();
Du sendest die adresse, und danach sofort ein command byte, ohne
subadresse.
Siehe Fig.17 und 18, dir fehlt das control byte. (bei mir subaddr
genannt)
Außerdem würde ich für den Anfang nicht alles auf einmal senden, sondern
in meiner oben geposteten Abfolge. Das ist die Standardabfolge, da
kannst du nichts mit falsch machen, zudem ist es dadurch einfacher zu
debuggen.
Diode, eine 08/15 Diode habe ich verwendet, nichts besonderes.
Bernhard Spitzer schrieb:> Mein Handy sagt zum Barcode VPDA6F-10D922-MA> Google hat dazu nix gefunden.
Also ich hab einen Treffer. Dort sind die aber genauso weit wie hier....
der Gast schrieb:> Ich kann doch bei dem Display kein Kontrats einstellen, da ich kein V0> zur referenz habe, ein Pin ist NC wo normalerweise V0 sein sollte.
Ja, schließ da auch einfach nichts an. Es war ja nur ein Vorschlag bevor
ich gesehen habe dass dein Code nicht stimmt.
Bisher steuerst du dein Display falsch an, es wird gar nichts machen, da
du bisher noch gar nicht in den CMD Bereich schreibst. Hast du das
behoben? Code?
okay, sorry falsch verstanden, mit dem ControlByte hast du völlig Recht,
aber ist es wirklich von nöten bei "JEDEM" Schreibbefehl die
Slaveadresse zu senden und auch den Bus zu starten und zu stoppen?
Nur in diesen Fällen:
1. du willst nun die Schreibadresse ändern, also nicht inkrementiell
schreiben. So gut wie alle i2c-Devices unterstützen inkrementielles
Schreiben.
2. du willst nun lesen
3. du adressierst nun ein anderes Device
Eigentlich reicht auch immer ein START senden vorheriges ohne STOP.
Soweit ich mich erinnere, fand ich aber schonmal die Anmerkung bei einem
EEPROM, daß dieses nur intern schreibt wenn als Abschluß ein STOP ankam.
Da muß man dann auch eventuell die Schreibzeit abwarten! Insbesondere
wenn der Slave-Chip keinen SCL-Treiber hat!!!
Daher schreibe ich das noch:
4. du erkennst einen Busfehler. Dann MUSS ein STOP gesendet werden. Gibt
da ne spezielle Sequenz mit 9 Bits.
Alles nur für Single-Master-Betrieb. Multi-Master habe ich nie
durchgespielt.
der Gast schrieb:> okay, sorry falsch verstanden, mit dem ControlByte hast du völlig Recht,> aber ist es wirklich von nöten bei "JEDEM" Schreibbefehl die> Slaveadresse zu senden und auch den Bus zu starten und zu stoppen?
Generell ist es immer von nöten diese Abfolge durchzuführen.
Jedoch kann man dem Slave, meist über die Subadresse, auch mitteilen,
dass man gerne mehr direkt hintereinander senden will, dann reduziert
sich der overhead, und man sendet Byte an Byte, wobei der Slave die
Adresse an der er das Byte in seinen RAM speichert dann automatisch
inkrementiert.
Da dazu aber genau darauf geachtet werden muss was man macht, und du
noch generell Probleme hast mit dem Display umzugehen, ist es eine
unnötige Schwierigkeit die du da einbaust.
Die Abfolge aus Start, Adresse, Subadresse, Byte, Stop, ist auch
leichter zu debuggen.
Nun zu deinem Code, der immer noch nicht stimmt, da du eben das Control
Byte noch nicht voll verstanden hast.
Figure 17, 18, Table 17 sind die wichtigen.
Figure 17b):
Start - Acknowledge - control byte (CO=1, RS=0) - command byte - control
byte (CO=0, RS=0) - acknowledge - stop
D.h. RS definiert dir ob das nächste Byte ein command oder ein control
byte ist.
CO definiert dir ob das darauf folgende Byte ein weiteres Control Byte
ist.
D.h. du musst vorerst nur 0b00000000 als control byte senden.
Sendest du 0b10000000 wird ein command byte erwartet und darauf hin
wieder ein control byte. Aber wie gesagt, verknüpfen kannst du später,
ich würde jetzt alles erst Schritt für Schritt machen.
Dann was du übehaupt sendest:
- Display-Adesse generell: Du weißt nicht ob SA0 = 0 oder 1 sein muss,
d.h. beides musst du mal seperat durchprobieren
- Mode-Set: Muss gesendet werden, da du jedoch nichts über dein Display
weißt solltest du hier experimentieren, d.h. B und M seperat
durchprobieren ob sich dadurch etwas ändert., wobei beim ersten
Durchgang B=0 und M=01 vllt. sinnvoll sind?
- load-data-pointer: bisher willst du noch nichts in das RAM schreiben,
also musst du auch den Pointer nicht platzieren, vor allem wohin
platzierst du ihn denn übehaupt? Weg damit.
- Device Select: Ich bin nicht genau dahinter gestiegen wie es
funktioniert und wie man diese Funktion nutzt und wann man diese Adresse
senden muss aber warum sendest du da einfach mal 0b11100111, wenn, dann
doch eher b11100000, wenn man Fig. 4 anschaut wird A0, A1, A2 auf GND
gesetzt sein, genauso wie SA0. (also korrigieren und auch mal ohne
ausprobieren)
- blink-select: das Teil mit dem man vielleicht am einfachsten das
Display überprüft, nur bisher hast du es deaktiviert. Wie wäre es mit
0b11110101?
Generell:
Offensichtlich ist das das erste mal dass du den I2C Bus verwendest.
Dann auch noch etwas ansprechen zu wollen, zu dem nur mäßige Doku
vorhanden ist, ist etwas idiotisch.
Du weißt nicht ob dein I2C Bus überhaupt funktioniert, du weißt nicht ob
dein Display richtig angeschlossen ist, du weißt nicht wie dein Display
intern die Adressen verdrahtet hat, du weißt nicht wie man ein
Datenblatt liest und den I2C Bus benutzt.
Probiere nochmal das aus was ich dir geschrieben habe, d.h. mit den
anderen Control Bytes und mit den richtigen Command bytes. Gewährleiste
dass das Program durchläuft. Poste ggf. auch nochmal den Code hier zur
Überprüfung.
Funktioniert es immer noch nicht, dann besorge dir ein I2C Bauteil zu
dem du ein Datenblatt bekommst, bspw. MCP9800, und bei dem du testen
kannst ob das mit deinem I2C Bus überhaupt funktioniert und lernen
kannst wie der I2C funktioniert. Danach kannst du dich dann nochmal an
dein Display wagen.
erstmal vielen Dank für deine Hilfe, trotz der Schmähenden Andeutungen,
also die Slaveadresse hab ich schon durchgetestet, so schlau war ich
auch schon und das mein I2C-Bus Daten sendet weiß ich auch, Dank eines
Oszilloskops. Ich werd deinen Rat befolgen trotzdem gern befolgen denn
dazu ist man ja auch hier wenn man nicht all zu viel Ahnung hat.
Frank M. schrieb:> Frag mich nicht mehr warum ich die Dioden rein gesetzt habe,> denke aber mich daran zu erinnern, dass dadurch der Kontrast geändert> wurde.
Die werden aus den 5V eine ca. 3.6V Versorgungsspannung gemacht haben.
der Gast schrieb:> erstmal vielen Dank für deine Hilfe, trotz der Schmähenden Andeutungen,> also die Slaveadresse hab ich schon durchgetestet, so schlau war ich> auch schon und das mein I2C-Bus Daten sendet weiß ich auch, Dank eines> Oszilloskops. Ich werd deinen Rat befolgen trotzdem gern befolgen denn> dazu ist man ja auch hier wenn man nicht all zu viel Ahnung hat.
Ich hatte, nachdem ich die I2C Routinen neu implementierte auf einer
neuen Leiterplatte mit einem neuem IC Probleme diesen QFN chip mit dem
I2C Bus anzusteuern. Ich hatte dort auch zu viel auf einmal geändert.
Neuer IC, neue Leiterplatte, neue Routine, ...
Um zu sehen ob zumindest der Bus und die Routine funktioniert habe ich
kurz solch einen Temperatursensor angelötet um damit rum zu testen. Als
gesichert war, dass der Bus funktioniert und der Ablauf des Lesens und
Schreibens stimmt, konnte ich eben die möglichen Fehlerquellen
eingrenzen - ein nicht richtig eingelöteter QFN chip war es am Ende und
ein falsches Lesen des Datenblatts, nämlich habe ich auch so ein Repeat
Bit überlesen und mich gewundert warum nur Mist ausgelesen wurde bzw der
Bus hing und blockierte da ich auch alle Daten auf einmal lesen wollte.
Das Ende meines letzten Posts klingt etwas harsch, aber du hast einfach
sehr viele Unbekannte und sehr viele mögliche Fehlerquellen und bist
auch nicht sicher im Umgang mit I2C bzw. der Art wie in Datenblättern so
ein Protokoll dargelegt wird.
Daher, falls die Tipps nichts brachten, wird es das beste sein, du
versuchst erst den I2C Bus mit einem einfacheren Bauteil mit
vollständigem Datenblatt in Betrieb zu nehmen und dessen Eigenheiten
lernen und dann nochmal das Display.
Ich bin gespannt auf deine Ergebnisse und hoffe das beste.
@Frank M.
Hab den Code nun geändert, das Display wird angesproche wie vorher auch
schon, mach sich dadurch bemerkbar dass das Display willkürliche
Darstellungen aus gibt.
Der Blink-Modus funktioniert auch, bewirkt aber nur, dass in zwei
verschiedenen Darstellungen hin und her geschaltet wird.
der Gast schrieb:> @Frank M.>> Hab den Code nun geändert, das Display wird angesproche wie vorher auch> schon, mach sich dadurch bemerkbar dass das Display willkürliche> Darstellungen aus gibt.> Der Blink-Modus funktioniert auch, bewirkt aber nur, dass in zwei> verschiedenen Darstellungen hin und her geschaltet wird.
Das hast du zum ersten mal erwähnt, dass was angezeigt wird, kannst du
genau sagen ab welchem Befehl? (nach dem ersten vermutlich?)
Da etwas angezeigt wird, kannst du davon ausgehen dass es richtig
angeschlossen ist.
Da der Blink Modus funktioniert (alles an/alles aus?) kannst du davon
ausgehen, dass du es richtig angesprochen hast.
Nun bist du fast am Ziel, sollte nichtmehr viel fehlen.
Dass nur Mist gerade angezeigt liegt nur daran, dass du den Display RAM
noch nicht geleert hast und mit sinnvollem aufgefüllt.
D.h. du kommentierst den Blink-Modus aus (wollen wir nicht) und
implementierst nun Fig. 17 c) und verschiebst den RAM Pointer an den
Anfang und füllst langsam den Display RAM auf (dann erkennst du wie er
aufgefüllt wird und ggf. musst du bank select und LCD drive mode
selection anpassen, damit es von links oben nach rechts unten sich
füllt.
1
Start
2
Adresse
3
Control Byte 10... (in Command register schreiben, nicht wiederholend)
4
Command Byte 0x00 senden (data-pointer auf den Anfang des Display RAMs verschieben, siehe Table 12)
5
Control Byte 01... (in RAM register schreiben, wiederholend)
6
Schleife von 0 bis 1001111 (79) mit jeweils 100ms Pause zwischendrin damit du den Aufbau am Display siehst
Blink Modus:
ein Wechsel zwischen
willkürliche Zeichen & alles aus
kommt aber drauf an, nach Spannungsabschaltung kann es auch sein
das es zwischen was anderem hin und her schaltet, wie du schon sagtest,
das was gerade im Ram steht?!
der Gast schrieb:> Blink Modus:>> ein Wechsel zwischen> willkürliche Zeichen & alles aus>> kommt aber drauf an, nach Spannungsabschaltung kann es auch sein> das es zwischen was anderem hin und her schaltet, wie du schon sagtest,> das was gerade im Ram steht?!
du wirst im Bit 'blink mode selection' momentan vermutlich 'blinking by
alternating display RAM banks' aktiviert haben, was doch mit einer
Beobachtung übereinstimmen könnte. Du kannst Spaßeshalber ja auch mal
den anderen modus 'normal blinking' ausprobieren.
Was ist das überhaupt für ein Display? Da auf Seite 5 steht, dass der IC
sowohl für Dot-Matrix als auch Segment-Displays eingesetzt werden kann?
Aber ersteinmal den Pseudo-Code implementieren und testen.
erfüllt weitesgehend den erwarteten Zweck, man kann nicht wirklich
sehen, dass die Symbole (von links oben nach rechts unten) aufgebaut
werden, es wird zwischen 3 verschiedenen Situationen hin und her
geschaltet, aber nie alles an oder alles aus.
Wenn du schon weist, dass es nicht funktioniert, warum machst du dann
nicht einfach mal das was ich dir gesagt habe, nicht mehr und nicht
weniger und nicht irgendeinen Mist den du erfunden hast, sinnlos ist und
absoluter Schwachsinn ist?
Wenn ich deinen Code anschaue, dann sehe ich dass du weder das getan
hast was ich dir hier:
Beitrag "Re: I2C-Signal SCL & SDA"
geschrieben habe, noch das, was ich dir hier:
Beitrag "Re: I2C-Signal SCL & SDA"
geschrieben habe.
1
i2c_start(Display+I2C_WRITE);
2
i2c_write(0b10000000);// ControlByte
3
i2c_write(0b11001101);// mode-set
4
5
i2c_write(0b10000000);// ControlByte
6
i2c_write(0b00000000);// load-data-pointer
7
i2c_stop();
Die control bytes stimmen nicht.
Warum machst du es nicht nach dem Ablauf, start, adresse, control, data,
stop wie ich dir empfohlen habe. Was hält dich davon ab???
Warum setzt du hier den data pointer?
Was ist mit der restlichen Initialisierungsroutine passiert die du davor
noch hattest? Ich sagte du sollst den Blink-Modus raus werfen, nicht
alles!!
1
i2c_start(Display+I2C_WRITE);
2
i2c_write(0b10000000);// ControlByte
3
4
for(x=0;x=79;x=x+1)
5
{
6
unsignedchary;
7
y=x;
8
9
i2c_write(y);
10
i2c_write(0b01100000);// ControlByte
11
i2c_write(0b11111111);// Daten
12
13
_delay_ms(100);
14
15
}
16
i2c_stop();
Was soll das erste Control Byte machen? Erkläre mir seine Funktion
bitte.
Was soll diese Schleife, sieht die so aus wie ich es dir gesagt habe?
NEIN! Warum? Du hast offensichlich keinen Plan wie man den I2C Bus
benutzt, ich aber schon, dann tu bitte auch das was ich dir sage. Ich
sage dir wie du ihn benutzen kannst, du ignorierst es, da du es ja
besser weißt.
Ich weiß nicht wie du drauf kommst eine Variable zu senden, wenn ich
explizit gesagt habe 0xFF.
Also, lese beide Posts durch die ich dir geschrieben habe, behebe alle
Probleme und mach es so wie ich dir geschrieben habe, in Kurz
(ausführlich habe ich es dir oft genug gesagt, also hier fehlt noch
einiges, es ist wirklich nur Pseudo-Code der total unvollständig ist!!):
1
Initialisieren (dazu gehört mehr als nur das Mode Byte)
2
While Schleife:
3
Daten pointer setzen
4
For schleife
5
Ram füllen
6
Ende For
7
Ende While
Wenn du weiterhin jeden Rat ignorierst, dann werde ich dir nicht weiter
helfen. Ich habe dir das Datenblatt vorgekaut und alle Schritte die du
machen musst genaustens beschrieben.
Bisher bist du absolut Lernresistent und hast so ziemlich alles was ich
gesagt habe ignoriert.
Bitte Code wieder posten.
Das Display funktioniert schon fast, es ist nicht mehr schwer, aber du
solltest eben auch zuhören bzw. lesen was der andere dir sagt, dann
könnte es schon längst problemlos laufen.
Beim nochmal drüber fliegen habe ich nun den Zweck deiner Schleife
verstanden. Ist aber falsch implementiert und ein Control Byte auch noch
um ein Bit versetzt.
Bitte versuche es so zu machen wie ich dir empfholen habe, d.h. (ich
gebe dir mal den code, da ich sah, dass du doch versucht hattest
zumindest die for schleife richtig zu implementieren, auch wenn du was
ganz was anderes gemacht hast als ich eigentlich gesagt habe)
was ich gesagt habe:
1
Start
2
Adresse
3
Control Byte 10... (in Command register schreiben, nicht wiederholend)
4
Command Byte 0x00 senden (data-pointer auf den Anfang des Display RAMs verschieben, siehe Table 12)
5
Control Byte 01... (in RAM register schreiben, wiederholend)
6
Schleife von 0 bis 1001111 (79) mit jeweils 100ms Pause zwischendrin damit du den Aufbau am Display siehst
7
RAM Byte 0xFF (alles an, vorerst)
8
Scheifenende
9
Stop
wenn man es nun 1:1 umsetzt, was sicherlich kein Hexenwerk sein sollte:
1
i2c_start(Display+I2C_WRITE);// Start // Adresse
2
i2c_write(0b10000000);// ControlByte 10...
3
i2c_write(0b00000000);// commandByte 0x00
4
i2c_write(0b01000000);// ControlByte 01..
5
for(x=0;x<=79;x=x+1)
6
{
7
i2c_write(0xFF);// RAM Byte 0xFF
8
_delay_ms(100);
9
}
10
i2c_stop();
PS: For loops gehen anders, kein Abbruchkriterium! Und Vergleiche in C
sind ==, nicht =
Es fehlt aber noch die richtige Initialisierung. Poste deinen Code bitte
immer damit wir dann immer über das selbe reden.
Doch wie wird der DataPointer um 1 erhöht? Das hab ich halt versucht in
meiner for-schleife zu verwirklichen, das dieser mit der for- schleife
auch um eins erhöht wird. Versteh grad nicht wie in deinem Vorschlag der
DataPointer erhöht wird.
der Gast schrieb:> kein bock mehr auf so Kommentare
das hoffe ich doch nicht, sonst habe ich hier nur Zeit verschwendet.
Zudem habe ich dir die Lösung schon fast gegeben.
Meine letzten zwei Posts waren 'direkter' ;-), aber es nervt einfach zu
sehen, wenn jemand etwas ganz anderes macht als ihm geraten wird und
dann sich wundert dass es immer noch nicht funktioniert.
derGast schrieb:> Doch wie wird der DataPointer um 1 erhöht? Das hab ich halt versucht in> meiner for-schleife zu verwirklichen, das dieser mit der for- schleife> auch um eins erhöht wird. Versteh grad nicht wie in deinem Vorschlag der> DataPointer erhöht wird.
So gefällt es mir schon besser. Anstatt einfach was anderes zu machen
lieber mal nachfragen.
"Datenblatt:
The display bytes are stored in the display RAM at the address specified
by the data pointer and the subaddress counter. Both data pointer and
subaddress counter are automatically updated"
Der Data Pointer wird automatisch um 1 incrementiert. Sonst würde auch
Fig 17c) keinen Sinn machen.
Wenn du das Ende des RAMs hast wird vermutlich auch der Subaddress
counter (Nutzen davon steht im Datenblatt) erhöht, den du dann aber
vermutlich wieder zurücksetzen musst, da du nur ein Display benutzt.
Deine Idee war nicht falsch, nur solltest du nicht mehere Methoden
miteinander vermixen, willst du den Pointer jedes mal setzen, so ist der
08/15 Weg (wie ich dir auch schon mehrmals gesagt habe):
1
for(unsignedcharx=0;x<=79;x++)
2
{
3
i2c_start(Display+I2C_WRITE);
4
i2c_write(0b10000000);// ControlByte für cmd, es folgt noch ein control
5
i2c_write(x);// Pointer im RAM setzen
6
i2c_write(0b01000000);// ControlByte für RAM, es folgt kein weiteres control