Der MCP23017 hat verschiedene Register.
Ein Register für (jeweils für einen Port)
IPOL die Polarität des Eingnags (ob ein 1 einem H oder L am Eingang entspricht)
IODIR ob eine Pin ein Eingang oder Ausgang ist.
GPINTEN, DEFVAL, INTCON, INTF, INTCAP für die Interruptfunktion eines Pins.
GPIO zum lesen bzw schreiben eines Ausgangs
OLAT zum schreiben der Ausgangspins (nur die als Aufgang definierten Pins werden dann wirklich geschrieben).
Für alle diese Register gilt, daß ein Bit einem Zustand eines Pins entspricht bzw betreffen.
Zum verändern eines Bits kannst Du die Bit Manipulations-Funktionen verwenden oder mittels logisch && bzw || die einzenen Bits des zu übertragenden Bytes setzen bzw löschen.
Andere Register haben funktionen die den gesamten MCP23017 betreffen und jedes Bit hat seine Bedeutung.
Die Übertrageung erfolgt immer als ganzes Byte bzw 16 Bit Wert in ein bestimmtes Register/ registerpaar ( je nach eingestelltem Mode . Darum mußt Du bei Ausgängen bzw registern die Du schreiben willst den letzten wert zwischenspeichern damit Du ihn verändern kannst.
Grüße Uwe