Hallo,
ich nutze einen Slave1 (AD-Wandler) via I2C. Jeweils 2 Pull-UPs (10K) an
SCL und SDA, funktioniert wunderbar. Wenn ich jetzt einen zweiten Slave
an den BUS von SCL hänge (es werden noch keinerlei Routinen von Slave2
abgearbeitet, sondern nur die reine Hardware Anbindung) funktioniert die
Kommunikation mit Slave 1 nicht mehr. Natürlich haben die beiden Slaves
eine andere Device Adresse.
Woran kann/könnte das liegen?
- Zu lange Leitung => Kapazität zu hoch
- Versorgung von Slave2 aus => er zeiht den Bus rutner
- Slave2 defekt => Bus gestört
Du wirst schon etwas genauer werden müssen.
Die PullUps sind zu groß. 4,7k gegen 5Volt oder 1,8k gegen 3,3Volt sind
üblicher.
Allerdings sollte das bei so einem kleinen Aufbau nicht zul Ausfall
führen.
Oliver R. schrieb:> bei so einem kleinen Aufbau
Woher weißt du dass der Aufbau klein ist. Hinterher stellt sich raus,
dass da 20m Kabel mit einem 10k Pullup hochgezogen werden müssen...
Hmm, es schien wirklich an den Pullups gelegen zu haben, obwohl in den
Datenblättern beider Slaver 10K postuliert sind. Wie kann sowas sein.
Mein Aufbau hie rauf dem Steckbrett mit einigen Steckbrücken ist dazu
sicherlich suboptimal.
SPI_OUT schrieb:> obwohl in den> Datenblättern beider Slaver 10K postuliert sind. Wie kann sowas sein.
Schau nach welcher Strom maximal in die SDA und SCL Pins hinenfließen
darf (wenn der Slave die auf Masse zieht) laut deren Datenblättern
(üblicherweise so um die 5mA). Du kannst die Pullups so lange kleiner
machen solange dieser Strom nicht überschritten würde, also 1.2k würden
evtl sogar auch noch gehen bei 5V.
Es gibt auch I²C Bus Treiber, die erlauben noch viel weiter
runterzugehen mit dem Widerstand und somit längere Strecken zu
überbrücken.
Ein niedrigerer Pullup verkleinert die Zeitkonstante des RC-Gliedes das
sich aus Leitungskapazität und Pullup bildet, somit erhöht ein kleinerer
Pullup die mögliche Taktfrequenz oder erlaubt eine längere Leitung bei
gleicher Taktfrequenz.
JEDOCH ist das ein zweischneidiges Schwert, ich hab schon Bauteile
gesehen die hatten schon mit 4.7k ihre liebe Not die Leitung noch
ordentlich auf Masse ziehen zu können, auch wenn im Datenblatt von
größeren Strömen die Rede war. Hier wirkt ein zu kleiner Pullup eher
kontraproduktiv.
Also im Zweifelsfalle mal das Oszi dranhängen (Tastkopf möglichst
hochomig einstellen) und sich die Signale anschauen.
Lothar Miller schrieb:> Woher weißt du dass der Aufbau klein istSPI_OUT schrieb:> Mein Aufbau hie rauf dem Steckbrett
Meine Glaskugel ist endlich aus der Reparatur zurück ...
Oder einfach nur glücklich geraten.
Bernd K. schrieb:> Ein niedrigerer Pullup verkleinert die Zeitkonstante des RC-Gliedes das> sich aus Leitungskapazität und Pullup bildet ...
Nicht zu vergessen die Eingangs- bzw. Ausgangskapazitäten der
angeschlossenen IC.
Vielen Dank für die ausführlichen Anmerkungen.
Ich habe das Problem, dass jetzt der Slvae2 (24LC64 EEPROM von
Microchip) nicht mit einem ACK auf die Deviaadresse reagiert. Ich
spreche das EEPROM mit demselben Code an mit dem ich schon andere Slaves
per I2C angesprochen habe.
A0 = High, A1, A2 = LOW:
MCU ist ein PIC32.
Jemand eine Ahnung woran das liegen könnte. Habe jetzt kürzere Kabel
genommen, PULL UPs rumexperimentiert und das EEPROM ausgetauscht.
Ohne Erfolg
Hallo,
sind das beides die gleichen ICs? Ansonsten kann es natürlich sein, dass
die nicht auf dieselbe Weise angesprochen werden können.
Was sind es denn für ICs, die beiden Slaves?
MfG Sebastian
Ich habe das EEPROM 24LC64 von Microchip jetzt ausgelagert und versuche
nur dieses anzusprechen. Nach Datenblatt und wie bei I2C gewohnt wird
nach der Sendung der Deviceadresse ein ACK erwartet. Das Empfangen der
Deviceadresse wird aber nicht vom EEPROM mit einem ACK bestätigt und das
Programm hängt in der oben angegebenen Schelife fest.
Dieselbe Routine hat bei einem anderen Slave jedoch schon einwandfrei
funktioniert. Ich vermute also eher keinen Softwarefehler. Was nach
Sendung der Deviceadresse kommt ist ja ersteinmal irrelevant, weil diese
Kommunikation schon nicht funktioniert.
Die beiden EEPROMs sind schon recht alt, eigentlich aber unberührt. Wie
kann ich testen ob diese überhuapt noch funktionstüchtig sind?
Gruß und Danke
1 | 0 | 1 | 0 | A2 | A1 | A0 | RW
sind 8 bit.
Die Adresse ist also bei dir (A0 = High, A1, A2 = LOW)
1 0 1 0 0 0 1 x (x ist das read/write bit)
Da deine Funktion Write_Byte_To_24LC64_EEPROM() eine 7-bit Adresse
erwartet, und hinten das R/W bit anhängt, musst du ihr folgende Adresse
geben (ohne das R/W bit):
1 0 1 0 0 0 1 = 0x51
Wenn das nicht funktioniert, probiere mal 0x82, vielleicht täusche ich
mich auch mit dem "R/W bit wird hinten angehängt".
SPI_OUT schrieb:> Das Empfangen der Deviceadresse wird aber nicht vom EEPROM mit einem ACK> bestätigt
Hast du ein Oszilloskop?
Das was du da gerade machst ist, wie mit verbundenen Augen Angeln, dann
gleich Grillen und dann probieren ob es ein Fisch war.
Mit einem Oszilloskop könntest du dir diese "Augenbinde" abnehmen und
deinen "Fang" besser bewerten...
wird dann in der Tat das WRITE BIT über I2C_WRITE hinden an die Adresse
angehangen.
-> 0x51 = 81
Müßte also passen.
> alle 127 Addressen durchprobieren
sehr witzig :)
SPI_OUT schrieb:> Müßte also passen.
Wenn alles passt, dann müsste es auch gehen. Hast du meinen Post nicht
gelesen oder nicht gesehen?
Merke: wenn du an einer Schraube drehst, und es ändert sich nichts, dann
war es die Falsche!
Bernd K. schrieb:> Schau nach welcher Strom maximal in die SDA und SCL Pins hinenfließen> darf (wenn der Slave die auf Masse zieht) laut deren Datenblättern> (üblicherweise so um die 5mA). Du kannst die Pullups so lange kleiner> machen solange dieser Strom nicht überschritten würde, also 1.2k würden> evtl sogar auch noch gehen bei 5V.
Das hilft dir garnicht. Da beide Seiten die Leitungen auf low ziehen
können müssen, zählt der Treiber mit dem kleinsten Strom. Viel einfacher
ist es den Wert aus der I2C Spec zu nehmen: 3mA
MfG Klaus
Lothar Miller schrieb:> SPI_OUT schrieb:>> Müßte also passen.> Wenn alles passt, dann müsste es auch gehen. Hast du meinen Post nicht> gelesen oder nicht gesehen?>> Merke: wenn du an einer Schraube drehst, und es ändert sich nichts, dann> war es die Falsche!
Ich habe leider kein Oszi, darf ich jetzt erst weitermachen, wenn ich
mir eins gekauft habe?
Danke trotzdem für den Hinweis. Ich möchte hier nicht als
beratungsresistent rüberkommen und fbin für alle Tipps dankbar!
Die Funktionen laufen jetzt soweit. Was nicht funktioniert ist das
Schreiben ins EEPROM und das direkt darauffolgende Lesen. D.h. ich muss
zuerst schreiben, dann z.b. Controller reseten und warten und dann erst
Lesen. Wie kann das sein?
SPI_OUT schrieb:>> alle 127 Addressen durchprobieren>> sehr witzig :)
War tatsächlich ernst gemeint.
Dafür gibt es ja Schleifen.
An deinem Code verstehe ich sowieso nicht, dass die Funktion
Write_Byte_To_24LC64_EEPROM()
als ersten Parameter "Address" erwartet, die du dann aber gar nicht
verwendest, da du direkt in der Funktion EEPROM_24LC64_ADDRESS
verwendest.
Würdest du hier "Address" verwenden, und den Aufruf in main() so machen:
könntest du auch locker alle 127 Adressen in main() durchprobieren
lassen, und müsstest halt in Write_Byte_To_24LC64_EEPROM()
DBPRINTF("Error: Sent byte was not acknowledged\n");
rausnehmen, und stattdessen die geackte Adresse anzeigen lassen.
EEPROM_24LC64_ADDRESS ist die "Device Adresse". Die richtige Adresse im
EEPROM wird nach dem Senden der Device Adresse geschickt (im obigen Code
noch nicht zu sehen -> erst high dann Low Byte).
Wie gesagt es funktioniert jetzt. Einzige Unklarheit ist warum direktes
Lesen auf Schreiben noch nicht funktioniert.
SPI_OUT schrieb:> Wie gesagt es funktioniert jetzt.
Und. Was hast du geändert?
Lass uns nicht dumm sterben. Wenn wieder mal wer mit ähnlichen Symptomen
kommt, werden sich einige erinnern und überlegen ob sein Fall ähnlich
gelagert sein könnte.
SPI_OUT schrieb:> Was nicht funktioniert ist das> Schreiben ins EEPROM und das direkt darauffolgende Lesen. D.h. ich muss> zuerst schreiben, dann z.b. Controller reseten und warten und dann erst> Lesen. Wie kann das sein?
Du musst warten bis das EEProm die Daten Programmiert hat.
Im Datenblatt findest du die ungefähren Zeiten.
Ob das Programmieren abgeschlossen ist, findest du durch das sogenannte
"ACKNOWLEDGE POLLING" heraus. (Datenblatt Seite 9)
Klaus schrieb:> Da beide Seiten die Leitungen auf low ziehen> können müssen, zählt der Treiber mit dem kleinsten Strom.
Hab ich doch gesagt (implizit zumindest).
Karl Heinz schrieb:> SPI_OUT schrieb:>>> Wie gesagt es funktioniert jetzt.>> Und. Was hast du geändert?
Der Fehler war wieder einmal auf eine Unkonzentriertheit zurückzuführen.
Ich habe beim Lesebefehl bei der Device-adressierung das falsche Makro
eingefügt, nämlich
so konnte natürlich nie der richtige Slave adressiert werden. Vielen
Dank auch nochmal an Michael für die Ausführungen bzgl. des ACKNOWLEDGE
POLLING.
Gruß