Posts by killerplautze

    Dieser Thread ist schon etwas aelter, aber hier dennoch mein Loesungsansatz :D :

    Um Bits innerhalb eines Bytes zu manipulieren ist "bitwise" Manipulation mit log. Operatoren und Bit-Masken sinnvoll.
    Die fokussierten Register des MCP23017 muessen also bei jedem i2c-write komplett gesetzt werden. Dabei sind die vorherigen Zustaende der nicht betrachteten Bits, zusammen mit den gaenderten Bits als ein neues Byte in das betroffene Register zu schreiben.

    Beispiele zum Testen in Python:


    1.) Ausgabe von dez 228 im Binaerformat

    Code
    >>> print('{:08b}'.format(228))
    11100100


    2.) Bit1 auf 1 setzen, ohne die restlichen Bits im Ausgangswert zu aendern

    • Ausgangszustand: der dezimale Wert 228, entspricht binaer 11100100 und ist gegeben
    • Absicht: Bit1 auf 1 setzen ohne Bit0 sowie Bit2-Bit7 zu aendern
    • Lösung: gegebenen Wert binaer ueber "log. ODER" mit der Bit-Maske der zu setzenden Bits verknuepfen
    • Vorgehen: Bit-Maske efinieren ... fuer Bit1 = 1 ergibt sich Bit-Maske 00000010 = dezimal 2
    • 11100100 ODER 00000010 = 11100110; Python-Operator fuer "log. ODER" = "|"
    Code
    >>> print('{:08b}'.format(228 | 2))            
    11100110

    3.) Bit1 auf 0 setzen, ohne die restlichen Bits im Ausgangszustand zu aendern

    • Ausgangszustand: der dezimale Wert 230, entspricht binaer 11100110 und ist gegeben
    • Absicht: Bit1 auf 0 setzen ohne Bit0 sowie Bit2-Bit7 zu aendern
    • Lösung: gegebenen Wert binaer ueber "log. UND" mit der negierten Bit-Maske der zu setzenden Bits verknuepfen
    • Vorgehen: Bit-Maske definieren ... fuer Bit1 = 1 ergibt sich Bit-Maske 00000010 = dezimal 2
    • 11100110 UND (NICHT(00000010)) = 11100100; Python-Operator fuer "log. UND" = "&", fuer "NICHT" = "~"
    Code
    >>> print('{:08b}'.format(230 & ~2))            
    11100100

    4.) Multiple Bits in einem Durchgang aendern ...

    Code
    >>> print('{:08b}'.format(228 | 3))  # gegeben: dez 228; bin 11100100; Bit0 und Bit1 setzen; Bit-Maske 00000011 entspricht dez 3
    11100111
    >>> print('{:08b}'.format(231 & ~3)) # gegeben: dez 231; bin 11100111; Bit0 und Bit1 löschen; Bit-Maske 00000011 entspricht dez 3 
    11100100


    Skript-Beispiel (unter Verwendung des SMBUS-I2C-Moduls):

    SMBUS kommt mit Hex-Werten im Format 0x00 und Dez-Werten im Integerformat, auch gemischt, zurecht.
    Das Integerformat funktioniert in diesem Zusammenhang, bis jetzt, sehr gut.
    Die Bit-Masken lassen sich recht gut und schnell mit Integer-Werten festlegen.
    TIP: Etwas Ordnung bei der Zuweisung / Verschaltung der General Purpose Pins am MCP23017 erspart heftigste Kopfschmerzen :D

    Ein Problem, mit dem ich in diesem Zusammenhang, noch kaempfe:
    Jeder Veränderung der MCP23017-Register-Bits muss ein Auslesen des betroffenen Registers vorweg gehen, um eine Ausgangsbasis zur Bit-Manipulation zu schaffen.
    Unnötige I2C-Transfer (z.B.: Register auslesen) ist aber unschoen, besonders wenn rel. viele Daten transferriert werden muessen.
    Ich ueberlege daher, die Register-Werte nicht immer aus dem MCP23017 auszulesen, sondern groesstenteils innerhalb des Programms in Variablen zu fuehren bzw. zu aendern. Wenn die Variablen aber nicht mehr die aktuellen Werten habe, wird ggf. das ganze Programm inkonsistent. Eine gute Mischung zwischen Auslesen und in Fuehren in separaten Variablen muss gefunden werden ... :s