Also... Nachdem ich aktuell etwas Schwierigkeiten mit besagtem Thema hatte
möchte ich für die "Mit-Dummies" und Anfänger in der Richtung Hilfestellung geben.
Dazu habe ich begonnen simple (absichtlich primitive) kurze programme zu erstellen
mit denen man den MCP kennenlernen kann.
Mir ist klar, das man das meiste evtl. mit der hälfte Code hätte lösen können...
aber es soll eben für "Neueinsteiger" lesbar und eingängig sein!
Bitte schaut euch dazu diese Codes durch und gebt fleissig Kritik.
Testprogramm "Simpler_Ausgangstest":MCP23017_Simpler_Ausgangstest.bas
Code:'********************************************************************** '** Programmbeschreibung ** '********************************************************************** '** Funktionstest MCP23017 !!! '** Alle GPA und GPB werden auf Ausgang eingestellt und getoggelt. '** So Kann man ganz einfach (z.B. mit LED + passendem Vorwiderstand) '** an den Pins testen, ob der MCP23017 reagiert. '** Der MCP erhöht in der Standardeinstellung bei jedem folgenden '** Schreib/Lesezugriff AUTOMATISCH die Registeradresse! '** '** Anschlüsse in diesem Test verwendet: '** >SDA und SCL direkt mit dem Kontroller verbinden und '** jeweils einen Widerstand als Pullup gegen + verbinden (Ca 4 bis 5 kOhm). '** >+ und - direkt anschliessen. '** >Resetpin mit + verbinden. '** >A0/A1/A2 (Adresspins) mit - verbinden. '********************************************************************** $regfile = "M328pdef.dat" $crystal = 16000000 $baud = 38400 '********************************************************************** '** Pins '********************************************************************** Config Sda = Portc.4 ' I2C Data. Config Scl = Portc.5 ' I2C Clock. Config I2cdelay = 10 ' Geschwindigkeit des I2C-Bus '********************************************************************** '** Subroutinen '********************************************************************** ' Subroutine fürs senden der Daten an den MCP23017. Declare Sub I2c_mcp23016_write(byval Reg As Byte , Byval Abyte As Byte , Byval Bbyte As Byte) '********************************************************************** '** Variablen/Konstanten '********************************************************************** ' Die Adresse des MCP23017 in Hexform (mit A0/A1/A2 jeweils 0 bzw auf Gnd gelegt) Const Mcp23016_adress_w = &H40 ' Write Adresse des MCP23017: 0 1 0 0 _0 0 0_ 0 Const Mcp23016_adress_r = &H41 ' Read Adresse des MCP23017: 0 1 0 0 _0 0 0_ 1 (hier nicht verwendet) Dim Reg As Byte ' enthält das Start-Register, in das geschrieben bzw. aus dem gelesen wird Dim Abyte As Byte ' Diese Variablen werden zum Schreiben verwendet Dim Bbyte As Byte '********************************************************************** '** Haupt-Programm '********************************************************************** 'Neustart Waitms 100 ' Kurze Pause bei Neustart Mcp_initialisieren: Reg = &H00 ' erstmal beim Register IODIRA mit Schreiben beginnen Call I2c_mcp23016_write(reg , &H00 , &H00) ' IODIRA und IODIRB alle auf Ausgänge einstellen Testfunktion: Do Reg = &H14 ' jetzt beim Register OLATA mit Schreiben beginnen Call I2c_mcp23016_write(reg , &HFF , &HFF) ' OLATA und OLATB ... beide auf 1 stellen Portb.0 = 1 ' Alle Ausgänge einschalten Waitms 75 Call I2c_mcp23016_write(reg , &H00 , &H00) ' OLATA und OLATB ... beide auf 0 Stellen Portb.0 = 0 ' Alle Ausgänge ausschalten Waitms 75 Loop End '********************************************************************** '** Subroutinen '********************************************************************** ' Daten auf MCP23017 schreiben/senden Sub I2c_mcp23016_write(byval Reg As Byte , Byval Abyte As Byte , Byval Bbyte As Byte) I2cstart 'Start senden I2cwbyte Mcp23016_adress_w 'Adresse fürs Schreiben senden I2cwbyte Reg 'Registeradresse die als erstes beschrieben werden soll I2cwbyte Abyte 'Erstes Daten-Byte Senden I2cwbyte Bbyte 'Zweites Daten-Byte senden (wird automatisch ins nächste Register geschrieben) I2cstop 'Stop senden Waitus 50 'Kurze Wartezeit einhalten um den I2C-Bus wieder "frei zu machen" End Sub
Testprogramm "Register_Auslesen":MCP23017_Register_auslesen.bas
Grüsse, JoeCode:'********************************************************************** '** Programmbeschreibung ** '********************************************************************** '** Funktionstest MCP23017 !!! '** Alle Register des MCP23017 werden ausgelesen und noch als Beispiel '** GPIOA und GPIOB einzeln ausgelesen. '** Der MCP erhöht in der Standardeinstellungbei jedem folgenden '** Schreib/Lesezugriff AUTOMATISCH die Registeradresse! '** '** Anschlüsse in diesem Test verwendet: '** >SDA und SCL direkt mit dem Kontroller verbinden und '** jeweils einen Widerstand als Pullup gegen + verbinden (Ca 4 bis 5 kOhm). '** >+ und - direkt anschliessen. '** >Resetpin mit + verbinden. '** >A0/A1/A2 (Adresspins) mit - verbinden. '********************************************************************** $regfile = "M328pdef.dat" $crystal = 16000000 $baud = 38400 '********************************************************************** '** Pins '********************************************************************** Config Sda = Portc.4 ' I2C Data. Config Scl = Portc.5 ' I2C Clock. Config I2cdelay = 10 ' Geschwindigkeit des I2C-Bus '********************************************************************** '** Subroutinen '********************************************************************** ' Subroutine fürs senden der Daten an den MCP23017. Declare Sub I2c_mcp23016_write_two(byval Reg As Byte , Byval Abyte As Byte , Byval Bbyte As Byte) Declare Sub I2c_mcp23016_read_all Declare Sub I2c_mcp23016_read_one(byval Reg As Byte) '********************************************************************** '** Variablen/Konstanten '********************************************************************** ' Die Adresse des MCP23017 in Hexform (mit A0/A1/A2 jeweils 0 bzw auf Gnd gelegt) Const Mcp23016_adress_w = &H40 ' Write Adresse des MCP23017: 0 1 0 0 _0 0 0_ 0 Const Mcp23016_adress_r = &H41 ' Read Adresse des MCP23017: 0 1 0 0 _0 0 0_ 1 Dim Reg As Byte ' enthält das Start-Register, in das geschrieben bzw. aus dem gelesen wird Dim Abyte As Byte ' Diese Variablen werden zum Schreiben verwendet Dim Bbyte As Byte 'Variablen jeweils für die einzelnen Registerinhalte Dim Aa As Byte Dim Ab As Byte Dim Ba As Byte Dim Bb As Byte Dim Ca As Byte Dim Cb As Byte Dim Da As Byte Dim Db As Byte Dim Ea As Byte Dim Eb As Byte Dim Fa As Byte Dim Fb As Byte Dim Ga As Byte Dim Gb As Byte Dim Ha As Byte Dim Hb As Byte Dim Ia As Byte Dim Ib As Byte Dim Ja As Byte Dim Jb As Byte Dim Ka As Byte Dim Kb As Byte Dim Xx As Byte 'Die Menge an Variablen ist zwar unangebracht und kann leicht "eleganter" gelöst werden... 'soll hier aber den Code "einfacher" gestalten um die Vorgänge besser zu zeigen '********************************************************************** '** Haupt-Programm '********************************************************************** 'Neustart Waitms 100 ' Kurze Pause bei Neustart Do Alle_register_auslesen: Reg = &H00 ' Register, bei dem mit dem Auslesen angefangen werden soll Print ">Alle Register Auslesen..." Call I2c_mcp23016_read_all ' Auslesen beginnen Print ">IODIRA : " ; Bin(aa) Print ">IODIRB : " ; Bin(ab) Print ">IOPOLA : " ; Bin(ba) Print ">IOPOLB : " ; Bin(bb) Print ">GPINTENA: " ; Bin(ca) Print ">GPINTENB: " ; Bin(cb) Print ">DEFVALA : " ; Bin(da) Print ">DEFVALB : " ; Bin(db) Print ">INTCONA : " ; Bin(ea) Print ">INTCONB : " ; Bin(eb) Print ">IOCON : " ; Bin(fa) Print ">IOCON : " ; Bin(fb) Print ">GPPUA : " ; Bin(ga) Print ">GPPUB : " ; Bin(gb) Print ">INTFA : " ; Bin(ha) Print ">INTFB : " ; Bin(hb) Print ">INTCAPA : " ; Bin(ia) Print ">INTCAPB : " ; Bin(ib) Print ">GPIOA : " ; Bin(ja) Print ">GPIOB : " ; Bin(jb) Print ">OLATA : " ; Bin(ka) Print ">OLATB : " ; Bin(kb) Print ">" Waitms 100 Einzelnes_register_auslesen: ' hier als Beispiel GPIOA und GPIOB Reg = &H12 ' Register das ausgelesen werden soll Call I2c_mcp23016_read_one(reg) ' Auslesen beginnen Print ">Gelesenes Register " ; Hex(reg) ; " (Hex) enthaelt die Werte: " ; Bin(xx) Print ">" Waitms 100 Reg = &H13 ' Wie zuvor nur diesmal das Register Hex13 auslesen Call I2c_mcp23016_read_one(reg) Print ">Gelesenes Register " ; Hex(reg) ; " (Hex) enthaelt die Werte: " ; Bin(xx) Print ">" Waitms 100 Wait 3 ' 3 Sekunden warten bevor von vorne begonnen wird Loop End '********************************************************************** '** Subroutinen '********************************************************************** ' Daten auf MCP23017 schreiben/senden (hier nicht verwendet) Sub I2c_mcp23016_write_two(byval Reg As Byte , Byval Abyte As Byte , Byval Bbyte As Byte) I2cstart 'Start senden I2cwbyte Mcp23016_adress_w 'Adresse fürs Schreiben senden I2cwbyte Reg 'Registeradresse die als erstes beschrieben werden soll I2cwbyte Abyte 'Erstes Daten-Byte Senden I2cwbyte Bbyte 'Zweites Daten-Byte senden (wird automatisch ins nächste Register geschrieben) I2cstop 'Stop senden Waitus 50 'Kurze Wartezeit einhalten um den I2C-Bus wieder "frei zu machen" End Sub ' Daten vom MCP23017 abrufen (hier z.b. ALLE Register nacheinander) Sub I2c_mcp23016_read_all I2cstart 'Start senden I2cwbyte Mcp23016_adress_w 'Adresse fürs Schreiben senden I2cwbyte Reg 'Registeradresse die als erstes gelesen werden soll I2cstop 'Stop senden I2crepstart 'RepeatedStart senden I2cwbyte Mcp23016_adress_r 'Adresse fürs Lesen senden. Der MCP folgt dieser Aufforderung mit der Ausgabe des Registerinhalts I2crbyte Aa , Ack 'Registerinhalt in Variable übernehmen und mit "Ack" zum weiteren senden auffordern I2crbyte Ab , Ack 'usw. I2crbyte Ba , Ack 'usw. I2crbyte Bb , Ack I2crbyte Ca , Ack I2crbyte Cb , Ack I2crbyte Da , Ack I2crbyte Db , Ack I2crbyte Ea , Ack I2crbyte Eb , Ack I2crbyte Fa , Ack I2crbyte Fb , Ack I2crbyte Ga , Ack I2crbyte Gb , Ack I2crbyte Ha , Ack I2crbyte Hb , Ack I2crbyte Ia , Ack I2crbyte Ib , Ack I2crbyte Ja , Ack I2crbyte Jb , Ack I2crbyte Ka , Ack I2crbyte Kb , Nack 'Registerinhalt in Variable übernehmen und mit "Nack" beenden I2cstop 'Stop senden Waitus 50 'Kurze Wartezeit einhalten um den I2C-Bus wieder "frei zu machen" End Sub ' Daten vom MCP23017 abrufen (hier z.b. nur EIN Register) Sub I2c_mcp23016_read_one I2cstart 'Start senden I2cwbyte Mcp23016_adress_w 'Adresse fürs Schreiben senden I2cwbyte Reg 'Registeradresse die als erstes gelesen werden soll I2cstop 'Stop senden I2crepstart 'RepeatedStart senden I2cwbyte Mcp23016_adress_r 'Adresse fürs Lesen senden. Der MCP folgt dieser Aufforderung mit der Ausgabe des Registerinhalts I2crbyte Xx , Nack 'Registerinhalt in Variable übernehmen und mit "Nack" beenden I2cstop 'Stop senden Waitus 50 'Kurze Wartezeit einhalten um den I2C-Bus wieder "frei zu machen" End Sub







Zitieren

Lesezeichen