Problem beim Schreiben in MCP23017 I/O Expander-Register (i2c)

Ich erstelle ein einfaches Kabeltestergerät und verwende I2C als Schnittstelle zu zwei MCP23017-E / A-Expander-Chips.

In meinem Code hat jeder MCP23017-Slave seine eigene Adresse und ich kann mit beiden ordnungsgemäß über I2C kommunizieren.

Die Idee ist, dass beide Enden eines "Kabels" in die beiden Buchsen gesteckt werden. Derzeit habe ich es so programmiert, dass es mit nur 8 Drähten arbeitet (unter Verwendung von nur GPA7-GPA0 auf beiden Chips). Grundsätzlich ist die Idee, dass ein logisch hoher Impuls einzeln auf jedem Draht (8-maliges Schleifen) vom ersten MCP23017-Chip (Pins als Ausgang konfiguriert und ist Slave 1) gesendet und vom zweiten MCP23017-Chip (Pins als Eingang konfiguriert und ist Sklave 2). Jetzt leuchten die LEDs einwandfrei und zeigen an, dass die Verbindung besteht, aber ich kann sie nicht dazu bringen, in die Register von Slave 2 zu schreiben.

Ich schreibe auf die ersten Chips OLATA und lese aus den GPIOA-Registern der zweiten Chips (Slave 2). Wenn also OLATA auf GPA7 (erster Chip) hoch ist, möchte ich den GPIOA GPA7-Pin auf dem zweiten Chip lesen. Über diese Lesevorgänge kann ich bitweise Operationen ausführen, um die Kabeltypen usw.

Mein Problem ist, dass, obwohl alle LEDs wie erwartet leuchten, nichts auf den zweiten (untersten) I/O-Expander-Chip geschrieben wird. Dies ist nicht gut für mich, da ich Daten in die Register schreiben muss, damit ich den Wert in diesen Registern lesen kann, um Operationen auszuführen. Der relevante I2C-Code für den I/O-Expander ist unten angegeben, diese drei Funktionen werden jeweils 8 Mal in der gezeigten Reihenfolge ausgeführt, eine für jeden GPAx-Pin:

http://pastebin.com/c3H2pbZp

Nun besteht das Problem darin, dass nichts in die ReadPin-Variable geschrieben wird, sie ist für alle 8 GPAx-Pins auf Slave 2 (unterster I/O-Expander-Chip) leer. Auch uint8_t Value ist 1<

Irgendwelche Ideen? Bitte helfen Sie, da dies das einzige Hauptproblem ist, das mich daran hindert, mit dem Schreiben anderer Programmlogik fortzufahren.

Danke!

PS: Zu Ihrer Information, keiner meiner Interrupt-Pins auf beiden MCP23017-Chips ist mit irgendetwas verbunden und die Reset-Pins sind mit VCC verbunden. Auch die als Eingänge des zweiten Slaves eingerichteten GPAx-Pins sind nicht mit Widerständen verbunden. Nur den Pin und dann die LED auf GND.

BEARBEITEN: Schaltplan: (Rechtsklick zur Vollansicht)

http://www.avrfreaks.net/modules/PNphpBB2/files/cable_tester_schematic_107.png

Ja, ich weiß auch, dass auf dem Schaltplan keine GND-Verbindung in VSS für Slave 1 vorhanden ist, aber bitte beachten Sie, dass ich mein derzeitiges Setup auf einem Protoboard mit allen Verbindungen, einschließlich dieser VSS-Verbindung, korrekt verdrahtet habe.

Ein Schaltplan könnte viel helfen.
Schema hinzugefügt!
Ich bin hier verwirrt - wo werden die Kabel eingesteckt? Die einzigen Buchsen, die ich sehen kann (M14 und M16PTH), haben alle Stifte mit Masse verbunden. Die LEDs sollten also für den Ausgangstreiber leuchten, aber keine LEDs (oder Daten auf dem IC) auf der Empfangsseite des Kabels.
Ein Kabelende wird auf M14 gesteckt, das andere auf M16. Zu diesem Zeitpunkt habe ich keine echten Kabel - zum Testen verwende ich einfach 8 Drähte. Also ein Kabel von GPA7 (Slave 1) zu GPA7 (Slave 2), ein anderes Kabel von GPA6 (Slave 1) zu GPA6 (Slave 2) usw. Außerdem interessiert mich nur, wo ich im Code falsch gelaufen bin. Ich bin ziemlich zuversichtlich, dass die Schaltung in Ordnung ist. Im Moment habe ich das Setup im Code (wie zu sehen) so, dass ich für GPA7 (Slave 1) ein Byte an OLATA schreibe und erwarte, den gleichen Wert zu sehen, wenn ich von GPA7 (Slave 2) über GPIOA lese. Gleiches gilt für die anderen GPAx-Pins. Ist das der richtige Ansatz??
Ich habe die internen Pullup-Widerstände für Slave 2 aktiviert und IODIRA als Eingänge eingestellt, aber wenn ich einen GPAx-Pin lese, scheint es, als würde nichts empfangen. Ist es möglich, von einem IO-Expander auf OLATA zu schreiben, ein Kabel daran anzuschließen (über GPAx) und es mit einem anderen IO-Expander zu verbinden und zu erwarten, dieselben Daten über GPIOA von ihm zurückzulesen?
In dem von Ihnen gezeigten Schema scheinen alle Anschlussstifte mit Masse verbunden zu sein , nicht die IC-IOs. Wenn Sie also ein Kabel in den Stecker stecken, liegt es immer auf Masse. Um ein Signal von einem IC zum anderen zu übertragen, müssten Sie die Kabel direkt an die IO-Pins anschließen. Wenn dies ein Fehler im Schaltplan ist, können Sie ihn beheben, um genau zu bestätigen, wie die Dinge eingerichtet sind.
Schaltplan bearbeitet. Immer noch das gleiche Problem. Ich habe alle LEDs entfernt, so dass ich nur eine Drahtverbindung habe, und am Hyperterminal-Ausgang erhalte ich: 11111111 11111111 usw. ... Wann für jeden GPAx-Pin, der getestet wird, sollte ich sehen (beim Lesen von Slave 2 jeden Pin auf einmal ) 00000001 00000010 00000100 usw... Was könnte falsch sein? Mir ist aufgefallen, dass ich bei aktivierten internen Pullupr-Widerständen alle 1 bekomme ... aber ohne sie sind es alle 0, es wurde keine Eingabe empfangen. Ich möchte auch erwähnen, dass ich dieses Setup auf einem Steckbrett habe ... Ich habe das nicht Strombegrenzungswiderstände zwischen GPAx-Pin und -Buchse
Soweit ich sehen kann, haben Sie den Schaltplan nicht bearbeitet, er ist immer noch derselbe ... Können Sie ihn reparieren, um uns genau zu zeigen , was Sie tun? Wenn Sie die Dinge wie gezeigt eingerichtet haben, kann es niemals funktionieren. Das Kabel ist nur ein Teil der Masse, keine Signale können darüber passieren. Es sollte sehr einfach sein, herauszufinden, was hier falsch ist, wenn Sie die erforderlichen Informationen bereitstellen.
Hier ist der Link: avrfreaks.net/modules/PNphpBB2/files/… Der Unterschied besteht darin, dass Masse zu VSS hinzugefügt wurde und die GND-Verbindungen auf JP3 und JP4 entfernt wurden.
Wenn es hilft, habe ich ein Bild mit dem angehängt, womit ich arbeite. Der Chip auf der linken Seite ist Slave 1 und der rechte ist Slave 2. Ignorieren Sie die gelben Kabel, sie sind für nichts programmiert. Die 8 weißen Kabel simulieren ein Kabel über JP3 und JP4. Von GPA7 bis GPA0. GPA7 auf der Seite von Slave 1 hat also ein Kabel, das zwischen ihm und GPA7 auf Slave 2 verbunden ist. Dies ist mein Setup. Vorher hatte ich 8 LEDs zwischen den 8 Drähten und GND auf der Slave 2-Seite angeschlossen, aber das wurde inzwischen entfernt. Hier ist das Bild meines aktuellen Setups: avrfreaks.net/modules/PNphpBB2/files/breadboard_setup_918.png
In einer Antwort wurde mehr hinzugefügt, da die Kommentare zu kurz sind. Welche I2C-Bibliothek verwendest du?
Ich verwende Peter Fleurys I2C-Bibliotheken
@ JackSparrow123 Der Link zum Schaltplan ist tot. Hast du die Datei zufällig in deinem Archiv gespeichert?

Antworten (1)

Okay, ich kann die Änderungen sehen.

Wie jetzt gezeigt, blockieren die LEDs auf dem empfangenden IC die Daten hoch, wenn sie umgekehrt sind. Die LEDs auf der Sendeseite sind auch keine gute Idee. Wenn Sie LEDs wünschen, müssen Sie sie von der Datenleitung über einen Widerstand auf Masse legen, nicht in Reihe mit der Verbindung zur Kabelbuchse.

Ich habe gerade dein Bild gesehen - es sieht so aus, als hättest du die LEDs entfernt, gut (ich wollte das gerade vorschlagen.. :-) )
Jetzt sieht es also so aus, als ob du direkte Verbindungen von IC1 zu IC2 hast. Wenn dies der Fall ist, dann sollte es funktionieren, wenn der Code (sieht auf einen Blick vernünftig aus) und die IC-Verkabelung korrekt sind.

Wenn Sie mit einem Multimeter bestätigen können, dass die Eingangspins eine hohe (oder niedrige) Spannung sehen und der gelesene Wert unterschiedlich ist, dann würde dies bestätigen, dass das eine oder andere der oben genannten Probleme vorliegt. Vielleicht legen Sie einfach eine bekannte Spannung direkt an und sehen, ob Sie das lesen können, okay)

Wenn Sie jedoch unterschiedliche Werte lesen, wenn die Klimmzüge ein- oder ausgeschaltet sind, scheint dies darauf hinzudeuten, dass der Messwert korrekt ist. Versuchen Sie, eine Gleichspannung zu lesen, und posten Sie die Ergebnisse. Ich überprüfe nur das Datenblatt für die ICs und werde in Kürze weitere hinzufügen.

EDIT - über die Klimmzüge:

Sie können die internen Pullups verwenden, wenn es Ihnen nichts ausmacht, dass sich die Leitung zu hoch "entspannt", wenn sie nicht angesteuert wird (dh Standardzustand 1). Diese werden häufig als Schnittstelle zu Open-Drain-Bussen oder für Taster an Masse usw. verwendet, um einen externen zu sparen hochziehen.
Wenn Sie jedoch einen niedrigen Standardzustand der Leitungen haben möchten (wie es bei Ihnen der Fall ist), benötigen Sie einen Pulldown, um das Schweben mit hoher Impedanz zu stoppen. Da der betreffende IC keine internen Pulldowns hat, müssen Sie sie extern hinzufügen.

BEARBEITEN - Doh! Ich habe das Problem gerade gesehen...

In Ihrem Code setzen Sie jeweils 1 Pin auf Ausgang und den Rest auf Eingänge. Das bedeutet, dass bei internen Klimmzügen die nicht angesteuerten Pins standardmäßig hoch sind! Wenn ein Pin auf Eingang eingestellt ist, ist er hochohmig , so effektiv ist es, als würde man dieses Ende der Leitung trennen, und die schwachen Pullups ziehen das empfangende Ende hoch.
Sie müssen alle Pins als Ausgänge behalten und nur jeweils einen hoch setzen, damit alle Pins angesteuert bleiben - versuchen Sie dies mit eingeschalteten Klimmzügen, es sollte funktionieren.
Wenn du weißt, dass die Leinen immer richtig gefahren werden, brauchst du die Klimmzüge nicht, aber es schadet nicht, sie anzulassen.

Hier ist der relevante Code (in der Initialisierungsregisterfunktion):

i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
    i2c_write(0x00);        // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
    i2c_write(~(Value));    // Set only one pin at a time as an output and everything else as inputs
    i2c_stop(); 

Ändern Sie es in:

i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
    i2c_write(0x00);        // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
    i2c_write(0x00);    // Set all pins as outputs
    i2c_stop();